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 <mutex> 24 #include <utility> 25 #include <vector> 26 27 #include "common/libs/utils/result.h" 28 #include "host/libs/input_connector/event_buffer.h" 29 #include "host/libs/input_connector/input_connection.h" 30 #include "host/libs/input_connector/input_connector.h" 31 32 namespace cuttlefish { 33 34 class InputDevice { 35 public: InputDevice(InputConnection conn)36 InputDevice(InputConnection conn) : conn_(conn) {} 37 virtual ~InputDevice() = default; 38 39 protected: 40 Result<void> WriteEvents(const EventBuffer& buffer); 41 42 private: 43 InputConnection conn_; 44 }; 45 46 class TouchDevice : public InputDevice { 47 public: TouchDevice(InputConnection conn)48 TouchDevice(InputConnection conn) 49 : InputDevice(conn) {} 50 51 Result<void> SendTouchEvent(int x, int y, bool down); 52 53 Result<void> SendMultiTouchEvent(const std::vector<MultitouchSlot>& slots, 54 bool down); 55 56 // The InputConnector holds state of on-going touch contacts. Event sources 57 // that can't produce multi touch events should call this function when it's 58 // known they won't produce any more events (because, for example, the 59 // streaming client disconnected) to make sure no stale touch contacts 60 // remain. This addresses issues arising from clients disconnecting in the 61 // middle of a touch action. 62 void OnDisconnectedSource(void* source); 63 64 private: 65 bool HasSlot(void* source, int32_t id); 66 67 int32_t GetOrAcquireSlot(void* source, int32_t id); 68 69 void ReleaseSlot(void* source, int32_t id); 70 NumActiveSlots()71 size_t NumActiveSlots() { 72 std::lock_guard<std::mutex> lock(slots_mtx_); 73 return slots_by_source_and_id_.size(); 74 } 75 NewTrackingId()76 int NewTrackingId() { return ++tracking_id_; } 77 78 int32_t UseNewSlot(); 79 80 std::mutex slots_mtx_; 81 std::map<std::pair<void*, int32_t>, int32_t> slots_by_source_and_id_; 82 std::vector<bool> active_slots_; 83 std::atomic<int> tracking_id_ = 0; 84 }; 85 86 class MouseDevice : public InputDevice { 87 public: MouseDevice(InputConnection conn)88 MouseDevice(InputConnection conn) 89 : InputDevice(conn) {} 90 91 Result<void> SendMoveEvent(int x, int y); 92 Result<void> SendButtonEvent(int button, bool down); 93 Result<void> SendWheelEvent(int pixels); 94 }; 95 96 class KeyboardDevice : public InputDevice { 97 public: KeyboardDevice(InputConnection conn)98 KeyboardDevice(InputConnection conn) 99 : InputDevice(conn) {} 100 101 Result<void> SendEvent(uint16_t code, bool down); 102 }; 103 104 class RotaryDevice : public InputDevice { 105 public: RotaryDevice(InputConnection conn)106 RotaryDevice(InputConnection conn) 107 : InputDevice(conn) {} 108 109 Result<void> SendEvent(int pixels); 110 }; 111 112 class SwitchesDevice : public InputDevice { 113 public: SwitchesDevice(InputConnection conn)114 SwitchesDevice(InputConnection conn) 115 : InputDevice(conn) {} 116 117 Result<void> SendEvent(uint16_t code, bool state); 118 }; 119 120 } // namespace cuttlefish 121