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 #ifndef DISTRIBUTED_INPUT_NODE_MANAGER_H 17 #define DISTRIBUTED_INPUT_NODE_MANAGER_H 18 19 #include <atomic> 20 #include <condition_variable> 21 #include <map> 22 #include <mutex> 23 #include <queue> 24 #include <string> 25 #include <thread> 26 27 #include "event_handler.h" 28 #include "nlohmann/json.hpp" 29 30 #include "constants_dinput.h" 31 #include "input_hub.h" 32 #include "i_session_state_callback.h" 33 #include "virtual_device.h" 34 35 namespace OHOS { 36 namespace DistributedHardware { 37 namespace DistributedInput { 38 constexpr uint32_t DINPUT_NODE_MANAGER_SCAN_ALL_NODE = 1; 39 constexpr uint32_t DINPUT_INJECT_EVENT_FAIL = 2; 40 const std::string INPUT_NODE_DEVID = "devId"; 41 const std::string INPUT_NODE_DHID = "dhId"; 42 /** 43 * @brief the unique id for the input peripheral. 44 * left is device networkid, right is dhId in that device. 45 */ 46 using DhUniqueID = std::pair<std::string, std::string>; 47 /** 48 * @brief a batch events form one device 49 * left: device networid where these events from 50 * right: the event batch 51 */ 52 using EventBatch = std::pair<std::string, std::vector<RawEvent>>; 53 class DistributedInputNodeManager { 54 public: 55 DistributedInputNodeManager(); 56 ~DistributedInputNodeManager(); 57 58 int32_t OpenDevicesNode(const std::string &devId, const std::string &dhId, const std::string ¶meters); 59 60 int32_t GetDevice(const std::string &devId, const std::string &dhId, VirtualDevice *&device); 61 void ReportEvent(const std::string &devId, const std::vector<RawEvent> &events); 62 int32_t CloseDeviceLocked(const std::string &devId, const std::string &dhId); 63 void StartInjectThread(); 64 void StopInjectThread(); 65 int32_t CreateVirtualTouchScreenNode(const std::string &devId, const std::string &dhId, const uint64_t srcWinId, 66 const uint32_t sourcePhyWidth, const uint32_t sourcePhyHeight); 67 int32_t RemoveVirtualTouchScreenNode(const std::string &devId, const std::string &dhId); 68 int32_t GetVirtualTouchScreenFd(); 69 70 void ProcessInjectEvent(const EventBatch &events); 71 72 /** 73 * @brief Get the Virtual Keyboard Paths By Dh Ids object 74 * 75 * @param dhKeys list for device identify({networkId, dhId}) 76 * @param virKeyboardPaths the matched keyboard device 77 * @param virKeyboardDhIds matched keyboard device identify 78 */ 79 void GetVirtualKeyboardPaths(const std::vector<DhUniqueID> &dhUniqueIds, 80 std::vector<std::string> &virKeyboardPaths); 81 void NotifyNodeMgrScanVirNode(const std::string &devId, const std::string &dhId); 82 void RegisterInjectEventCb(sptr<ISessionStateCallback> callback); 83 void UnregisterInjectEventCb(); 84 85 class DInputNodeManagerEventHandler : public AppExecFwk::EventHandler { 86 public: 87 DInputNodeManagerEventHandler(const std::shared_ptr<AppExecFwk::EventRunner> &runner, 88 DistributedInputNodeManager *manager); 89 ~DInputNodeManagerEventHandler() override; 90 91 void ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event) override; 92 private: 93 void ScanAllNode(const AppExecFwk::InnerEvent::Pointer &event); 94 95 using nodeMgrFunc = void (DInputNodeManagerEventHandler::*)( 96 const AppExecFwk::InnerEvent::Pointer &event); 97 std::map<int32_t, nodeMgrFunc> eventFuncMap_; 98 DistributedInputNodeManager *nodeManagerObj_; 99 }; 100 101 private: 102 void AddDeviceLocked(const std::string &networkId, const std::string &dhId, std::unique_ptr<VirtualDevice> device); 103 int32_t CreateHandle(const InputDevice &inputDevice, const std::string &devId, const std::string &dhId); 104 void ParseInputDeviceJson(const std::string &str, InputDevice &pBuf); 105 void ParseInputDevice(const nlohmann::json &inputDeviceJson, InputDevice &pBuf); 106 void ParseInputDeviceBasicInfo(const nlohmann::json &inputDeviceJson, InputDevice &pBuf); 107 void ParseInputDeviceEvents(const nlohmann::json &inputDeviceJson, InputDevice &pBuf); 108 void InjectEvent(); 109 110 void ScanSinkInputDevices(const std::string &devId, const std::string &dhId); 111 bool MatchAndSavePhysicalPath(const std::string &devicePath, const std::string &devId, const std::string &dhId); 112 bool IsVirtualDev(int fd); 113 bool GetDevDhUniqueIdByFd(int fd, DhUniqueID &dhUnqueId, std::string &physicalPath); 114 void SetPathForVirDev(const DhUniqueID &dhUniqueId, const std::string &devicePath); 115 void RunInjectEventCallback(const std::string &dhId, const uint32_t injectEvent); 116 117 /* the key is {networkId, dhId}, and the value is virtualDevice */ 118 std::map<DhUniqueID, std::unique_ptr<VirtualDevice>> virtualDeviceMap_; 119 std::mutex virtualDeviceMapMutex_; 120 std::atomic<bool> isInjectThreadCreated_; 121 std::atomic<bool> isInjectThreadRunning_; 122 std::mutex operationMutex_; 123 std::thread eventInjectThread_; 124 std::mutex injectThreadMutex_; 125 std::condition_variable conditionVariable_; 126 std::queue<EventBatch> injectQueue_; 127 int32_t virtualTouchScreenFd_; 128 std::once_flag callOnceFlag_; 129 std::shared_ptr<DInputNodeManagerEventHandler> callBackHandler_; 130 sptr<ISessionStateCallback> SessionStateCallback_; 131 }; 132 } // namespace DistributedInput 133 } // namespace DistributedHardware 134 } // namespace OHOS 135 136 #endif // DISTRIBUTED_INPUT_INJECT_H