• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2025 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_impl.h"
17 
18 #include "multimodal_input_connect_manager.h"
19 #include "bytrace_adapter.h"
20 #include "mmi_log.h"
21 
22 #undef MMI_LOG_TAG
23 #define MMI_LOG_TAG "InputDeviceImpl"
24 
25 namespace OHOS {
26 namespace MMI {
27 namespace {
28 constexpr std::string_view INPUT_DEV_CHANGE_ADD_DEV { "add" };
29 constexpr std::string_view INPUT_DEV_CHANGE_REMOVE_DEV { "remove" };
30 }
31 
GetInstance()32 InputDeviceImpl& InputDeviceImpl::GetInstance()
33 {
34     static InputDeviceImpl instance;
35     return instance;
36 }
37 
RegisterDevListener(const std::string & type,InputDevListenerPtr listener)38 int32_t InputDeviceImpl::RegisterDevListener(const std::string &type, InputDevListenerPtr listener)
39 {
40     CHKPR(listener, RET_ERR);
41     MMI_HILOGI("Register listener of change of input devices");
42 
43     bool needStartServer = false;
44     {
45         std::lock_guard<std::mutex> guard(devListenerMutex_);
46         auto iter = devListener_.find(type);
47         if (iter == devListener_.end()) {
48             MMI_HILOGE("Type of listener (%{public}s) is not supported", type.c_str());
49             return RET_ERR;
50         }
51 
52         auto &listeners = iter->second;
53         bool isNew = std::all_of(listeners.cbegin(), listeners.cend(),
54             [listener](InputDevListenerPtr tListener) {
55                 return (tListener != listener);
56             });
57         if (isNew) {
58             listeners.push_back(listener);
59             needStartServer = listeners.size();
60         }
61     }
62 
63     if (needStartServer) {
64         auto ret = StartListeningToServer();
65         if (ret != RET_OK) {
66             MMI_HILOGE("StartListeningToServer fail, error:%{public}d", ret);
67             std::lock_guard<std::mutex> guard(devListenerMutex_);
68             auto iter = devListener_.find(type);
69             if (iter != devListener_.end()) {
70                 iter->second.remove(listener);
71             }
72             return ret;
73         }
74     }
75 
76     MMI_HILOGI("Succeed to register listener of change of input devices");
77     return RET_OK;
78 }
79 
UnregisterDevListener(const std::string & type,InputDevListenerPtr listener)80 int32_t InputDeviceImpl::UnregisterDevListener(const std::string &type, InputDevListenerPtr listener)
81 {
82     bool needStopServer = false;
83     {
84         std::lock_guard<std::mutex> guard(devListenerMutex_);
85         auto iter = devListener_.find(type);
86         if (iter == devListener_.end()) {
87             MMI_HILOGE("Type of listener (%{public}s) is not supported", type.c_str());
88             return RET_ERR;
89         }
90 
91         auto &listeners = iter->second;
92         if (listener == nullptr) {
93             MMI_HILOGI("Unregister all listeners of change of input devices");
94             needStopServer = !listeners.empty();
95             listeners.clear();
96         } else {
97             MMI_HILOGI("Unregister listener of change of input devices");
98             size_t oldSize = listeners.size();
99             listeners.remove_if([listener](const auto &item) {
100                 return (item == listener);
101             });
102             needStopServer = (oldSize > 0) && listeners.empty();
103         }
104     }
105 
106     if (needStopServer) {
107         StopListeningToServer();
108     }
109     return RET_OK;
110 }
111 
OnDevListener(int32_t deviceId,const std::string & type)112 void InputDeviceImpl::OnDevListener(int32_t deviceId, const std::string &type)
113 {
114     CALL_DEBUG_ENTER;
115     MMI_HILOGI("Change(%{public}s) of input device(%{public}d)", type.c_str(), deviceId);
116 
117     std::vector<InputDevListenerPtr> listenersToNotify;
118     {
119         std::lock_guard<std::mutex> guard(devListenerMutex_);
120         auto iter = devListener_.find(CHANGED_TYPE);
121         if (iter == devListener_.end()) {
122             MMI_HILOGE("Find change failed");
123             return;
124         }
125         listenersToNotify.assign(iter->second.begin(), iter->second.end());
126     }
127 
128     BytraceAdapter::StartDevListener(type, deviceId);
129 
130     for (const auto &item : listenersToNotify) {
131         if (type == INPUT_DEV_CHANGE_ADD_DEV) {
132             item->OnDeviceAdded(deviceId, type);
133         } else if (type == INPUT_DEV_CHANGE_REMOVE_DEV) {
134             item->OnDeviceRemoved(deviceId, type);
135         }
136     }
137     BytraceAdapter::StopDevListener();
138 }
139 
GetInputDeviceIds(FunInputDevIds callback)140 int32_t InputDeviceImpl::GetInputDeviceIds(FunInputDevIds callback)
141 {
142     CALL_DEBUG_ENTER;
143     CHKPR(callback, RET_ERR);
144     std::vector<int32_t> ids;
145     if (MULTIMODAL_INPUT_CONNECT_MGR->GetDeviceIds(ids) != RET_OK) {
146         MMI_HILOGE("GetInputDeviceIds failed");
147         return RET_ERR;
148     }
149     callback(ids);
150     return RET_OK;
151 }
152 
GetInputDevice(int32_t deviceId,FunInputDevInfo callback)153 int32_t InputDeviceImpl::GetInputDevice(int32_t deviceId, FunInputDevInfo callback)
154 {
155     CALL_DEBUG_ENTER;
156     CHKPR(callback, RET_ERR);
157     std::shared_ptr<InputDevice> inputDevice = std::make_shared<InputDevice>();
158     if (MULTIMODAL_INPUT_CONNECT_MGR->GetDevice(deviceId, inputDevice) != RET_OK) {
159         MMI_HILOGE("GetDevice failed");
160         return RET_ERR;
161     }
162     callback(inputDevice);
163     return RET_OK;
164 }
165 
SupportKeys(int32_t deviceId,std::vector<int32_t> keyCodes,FunInputDevKeys callback)166 int32_t InputDeviceImpl::SupportKeys(int32_t deviceId, std::vector<int32_t> keyCodes, FunInputDevKeys callback)
167 {
168     CALL_DEBUG_ENTER;
169     CHKPR(callback, RET_ERR);
170     std::vector<bool> keystroke;
171     if (MULTIMODAL_INPUT_CONNECT_MGR->SupportKeys(deviceId, keyCodes, keystroke) != RET_OK) {
172         MMI_HILOGE("SupportKeys failed");
173         return RET_ERR;
174     }
175     callback(keystroke);
176     return RET_OK;
177 }
178 
GetKeyboardType(int32_t deviceId,FunKeyboardTypes callback)179 int32_t InputDeviceImpl::GetKeyboardType(int32_t deviceId, FunKeyboardTypes callback)
180 {
181     CALL_DEBUG_ENTER;
182     CHKPR(callback, RET_ERR);
183     int32_t keyboardType = 0;
184     if (MULTIMODAL_INPUT_CONNECT_MGR->GetKeyboardType(deviceId, keyboardType) != RET_OK) {
185         MMI_HILOGE("GetKeyboardType failed");
186         return RET_ERR;
187     }
188     callback(keyboardType);
189     return RET_OK;
190 }
191 
SetKeyboardRepeatDelay(int32_t delay)192 int32_t InputDeviceImpl::SetKeyboardRepeatDelay(int32_t delay)
193 {
194     CALL_DEBUG_ENTER;
195     if (MULTIMODAL_INPUT_CONNECT_MGR->SetKeyboardRepeatDelay(delay) != RET_OK) {
196         MMI_HILOGE("SetKeyboardRepeatDelay failed");
197         return RET_ERR;
198     }
199     return RET_OK;
200 }
201 
SetKeyboardRepeatRate(int32_t rate)202 int32_t InputDeviceImpl::SetKeyboardRepeatRate(int32_t rate)
203 {
204     CALL_DEBUG_ENTER;
205     if (MULTIMODAL_INPUT_CONNECT_MGR->SetKeyboardRepeatRate(rate) != RET_OK) {
206         MMI_HILOGE("SetKeyboardRepeatRate failed");
207         return RET_ERR;
208     }
209     return RET_OK;
210 }
211 
GetKeyboardRepeatDelay(std::function<void (int32_t)> callback)212 int32_t InputDeviceImpl::GetKeyboardRepeatDelay(std::function<void(int32_t)> callback)
213 {
214     CALL_DEBUG_ENTER;
215     CHKPR(callback, RET_ERR);
216     int32_t repeatDelay = 0;
217     if (MULTIMODAL_INPUT_CONNECT_MGR->GetKeyboardRepeatDelay(repeatDelay) != RET_OK) {
218         MMI_HILOGE("GetKeyboardRepeatDelay failed");
219         return RET_ERR;
220     }
221     callback(repeatDelay);
222     return RET_OK;
223 }
224 
GetKeyboardRepeatRate(std::function<void (int32_t)> callback)225 int32_t InputDeviceImpl::GetKeyboardRepeatRate(std::function<void(int32_t)> callback)
226 {
227     CALL_DEBUG_ENTER;
228     int32_t repeatRate = 0;
229     if (MULTIMODAL_INPUT_CONNECT_MGR->GetKeyboardRepeatRate(repeatRate) != RET_OK) {
230         MMI_HILOGE("GetKeyboardRepeatRate failed");
231         return RET_ERR;
232     }
233     callback(repeatRate);
234     return RET_OK;
235 }
236 
GetUserData()237 int32_t InputDeviceImpl::GetUserData()
238 {
239     return userData_;
240 }
241 
RegisterInputdevice(int32_t deviceId,bool enable,std::function<void (int32_t)> callback)242 int32_t InputDeviceImpl::RegisterInputdevice(int32_t deviceId, bool enable, std::function<void(int32_t)> callback)
243 {
244     CALL_DEBUG_ENTER;
245     CHKPR(callback, RET_ERR);
246     int32_t _id;
247     {
248         std::lock_guard<std::mutex> guard(inputDeviceMutex_);
249         _id = operationIndex_++;
250         inputdeviceList_[_id] = callback;
251     }
252     int32_t ret = MULTIMODAL_INPUT_CONNECT_MGR->SetInputDeviceEnabled(deviceId, enable, _id);
253     if (ret != RET_OK) {
254         MMI_HILOGE("Failed to register");
255         return ret;
256     }
257     return RET_OK;
258 }
259 
OnSetInputDeviceAck(int32_t index,int32_t result)260 void InputDeviceImpl::OnSetInputDeviceAck(int32_t index, int32_t result)
261 {
262     CALL_DEBUG_ENTER;
263     std::function<void(int32_t)> callback;
264     {
265         std::lock_guard<std::mutex> guard(inputDeviceMutex_);
266         auto iter = inputdeviceList_.find(index);
267         if (iter == inputdeviceList_.end()) {
268             MMI_HILOGE("Find index failed");
269             return;
270         }
271         callback = std::move(iter->second);
272         inputdeviceList_.erase(iter);
273     }
274     callback(result);
275 }
276 
OnConnected()277 void InputDeviceImpl::OnConnected()
278 {
279     bool shouldStartServer = false;
280     {
281         std::lock_guard<std::mutex> guard(devListenerMutex_);
282         auto iter = devListener_.find(CHANGED_TYPE);
283         shouldStartServer = (iter != devListener_.end()) && !iter->second.empty();
284     }
285 
286     if (!shouldStartServer) {
287         return;
288     }
289 
290     auto ret = StartListeningToServer();
291     if (ret != RET_OK) {
292         MMI_HILOGE("StartListeningToServer fail, error:%{public}d", ret);
293     }
294 }
295 
OnDisconnected()296 void InputDeviceImpl::OnDisconnected()
297 {
298     MMI_HILOGI("Disconnected from server");
299     isListeningProcess_.store(false);
300 }
301 
StartListeningToServer()302 int32_t InputDeviceImpl::StartListeningToServer()
303 {
304     if (isListeningProcess_.load()) {
305         return RET_OK;
306     }
307     MMI_HILOGI("Start monitoring changes of input devices");
308     int32_t ret = MULTIMODAL_INPUT_CONNECT_MGR->RegisterDevListener();
309     if (ret != RET_OK) {
310         MMI_HILOGE("RegisterDevListener to server fail, error:%{public}d", ret);
311         return ret;
312     }
313     isListeningProcess_.store(true);
314     return RET_OK;
315 }
316 
StopListeningToServer()317 void InputDeviceImpl::StopListeningToServer()
318 {
319     if (!isListeningProcess_.load()) {
320         return;
321     }
322     MMI_HILOGI("Stop monitoring changes of input devices");
323     auto ret = MULTIMODAL_INPUT_CONNECT_MGR->UnregisterDevListener();
324     if (ret != RET_OK) {
325         MMI_HILOGE("UnregisterDevListener from server fail, error:%{public}d", ret);
326     }
327     isListeningProcess_.store(false);
328 }
329 } // namespace MMI
330 } // namespace OHOS
331