1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <atomic> 20 #include <cstdint> 21 #include <cstdlib> 22 #include <map> 23 #include <memory> 24 #include <mutex> 25 #include <utility> 26 #include <vector> 27 28 #include "common/libs/utils/result.h" 29 #include "host/libs/input_connector/event_buffer.h" 30 #include "host/libs/input_connector/input_connection.h" 31 #include "host/libs/input_connector/input_connector.h" 32 33 namespace cuttlefish { 34 35 class InputDevice { 36 public: InputDevice(std::unique_ptr<InputConnection> conn,InputEventType event_type)37 InputDevice(std::unique_ptr<InputConnection> conn, InputEventType event_type) 38 : conn_(std::move(conn)), event_type_(event_type) {} 39 virtual ~InputDevice() = default; 40 41 protected: conn()42 InputConnection& conn() { return *conn_; } event_type()43 InputEventType event_type() const { return event_type_; } 44 45 private: 46 std::unique_ptr<InputConnection> conn_; 47 InputEventType event_type_; 48 }; 49 50 class TouchDevice : public InputDevice { 51 public: TouchDevice(std::unique_ptr<InputConnection> conn,InputEventType event_type)52 TouchDevice(std::unique_ptr<InputConnection> conn, InputEventType event_type) 53 : InputDevice(std::move(conn), event_type) {} 54 55 Result<void> SendTouchEvent(int x, int y, bool down); 56 57 Result<void> SendMultiTouchEvent(const std::vector<MultitouchSlot>& slots, 58 bool down); 59 60 // The InputConnector holds state of on-going touch contacts. Event sources 61 // that can't produce multi touch events should call this function when it's 62 // known they won't produce any more events (because, for example, the 63 // streaming client disconnected) to make sure no stale touch contacts 64 // remain. This addresses issues arising from clients disconnecting in the 65 // middle of a touch action. 66 void OnDisconnectedSource(void* source); 67 68 private: WriteEvents(const EventBuffer & buffer)69 Result<void> WriteEvents(const EventBuffer& buffer) { 70 CF_EXPECT(conn().WriteEvents(buffer.data(), buffer.size())); 71 return {}; 72 } 73 74 bool HasSlot(void* source, int32_t id); 75 76 int32_t GetOrAcquireSlot(void* source, int32_t id); 77 78 void ReleaseSlot(void* source, int32_t id); 79 NumActiveSlots()80 size_t NumActiveSlots() { 81 std::lock_guard<std::mutex> lock(slots_mtx_); 82 return slots_by_source_and_id_.size(); 83 } 84 NewTrackingId()85 int NewTrackingId() { return ++tracking_id_; } 86 87 int32_t UseNewSlot(); 88 89 std::mutex slots_mtx_; 90 std::map<std::pair<void*, int32_t>, int32_t> slots_by_source_and_id_; 91 std::vector<bool> active_slots_; 92 std::atomic<int> tracking_id_ = 0; 93 }; 94 95 class MouseDevice : public InputDevice { 96 public: MouseDevice(std::unique_ptr<InputConnection> conn,InputEventType event_type)97 MouseDevice(std::unique_ptr<InputConnection> conn, InputEventType event_type) 98 : InputDevice(std::move(conn), event_type) {} 99 100 Result<void> SendMoveEvent(int x, int y); 101 Result<void> SendButtonEvent(int button, bool down); 102 Result<void> SendWheelEvent(int pixels); 103 }; 104 105 class KeyboardDevice : public InputDevice { 106 public: KeyboardDevice(std::unique_ptr<InputConnection> conn,InputEventType event_type)107 KeyboardDevice(std::unique_ptr<InputConnection> conn, 108 InputEventType event_type) 109 : InputDevice(std::move(conn), event_type) {} 110 111 Result<void> SendEvent(uint16_t code, bool down); 112 }; 113 114 class RotaryDevice : public InputDevice { 115 public: RotaryDevice(std::unique_ptr<InputConnection> conn,InputEventType event_type)116 RotaryDevice(std::unique_ptr<InputConnection> conn, InputEventType event_type) 117 : InputDevice(std::move(conn), event_type) {} 118 119 Result<void> SendEvent(int pixels); 120 }; 121 122 class SwitchesDevice : public InputDevice { 123 public: SwitchesDevice(std::unique_ptr<InputConnection> conn,InputEventType event_type)124 SwitchesDevice(std::unique_ptr<InputConnection> conn, 125 InputEventType event_type) 126 : InputDevice(std::move(conn), event_type) {} 127 128 Result<void> SendEvent(uint16_t code, bool state); 129 }; 130 131 } // namespace cuttlefish 132