1 /* 2 * Copyright (C) 2018 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 #ifndef _UI_INPUTFLINGER_TOUCH_VIDEO_DEVICE_H 18 #define _UI_INPUTFLINGER_TOUCH_VIDEO_DEVICE_H 19 20 #include <android-base/unique_fd.h> 21 #include <input/TouchVideoFrame.h> 22 #include <stdint.h> 23 #include <array> 24 #include <optional> 25 #include <string> 26 #include <vector> 27 28 namespace android { 29 30 /** 31 * Represents a video device that uses v4l2 api to report touch heatmap data. 32 */ 33 class TouchVideoDevice { 34 public: 35 /** 36 * Create a new TouchVideoDevice for the path provided. 37 * Return nullptr upon failure. 38 */ 39 static std::unique_ptr<TouchVideoDevice> create(std::string devicePath); 40 ~TouchVideoDevice(); 41 hasValidFd()42 bool hasValidFd() const { return mFd.get() != INVALID_FD; } 43 /** 44 * Obtain the file descriptor associated with this video device. 45 * Could be used for adding to epoll. 46 */ getFd()47 int getFd() const { return mFd.get(); } 48 /** 49 * Get the name of this video device. 50 */ getName()51 const std::string& getName() const { return mName; } 52 /** 53 * Get the file path of this video device. 54 */ getPath()55 const std::string& getPath() const { return mPath; } 56 /** 57 * Get the height of the heatmap frame 58 */ getHeight()59 uint32_t getHeight() const { return mHeight; } 60 /** 61 * Get the width of the heatmap frame 62 */ getWidth()63 uint32_t getWidth() const { return mWidth; } 64 /** 65 * Direct read of the frame. Stores the frame into internal buffer. 66 * Return the number of frames that were successfully read. 67 * 68 * This function should not be called unless buffer is ready! 69 * This must be checked with select, poll, epoll, or similar api first. 70 * If epoll indicates that there is data ready to read, but this function 71 * returns zero, then it is likely an error occurred. 72 */ 73 size_t readAndQueueFrames(); 74 /** 75 * Return all of the queued frames, and erase them from the local buffer. 76 * The returned frames are in the order that they were received from the 77 * v4l2 device, with the oldest frame at the index 0. 78 */ 79 std::vector<TouchVideoFrame> consumeFrames(); 80 /** 81 * Get string representation of this video device. 82 */ 83 std::string dump() const; 84 85 private: 86 android::base::unique_fd mFd; 87 std::string mName; 88 std::string mPath; 89 90 uint32_t mHeight; 91 uint32_t mWidth; 92 93 static constexpr int INVALID_FD = -1; 94 /** 95 * How many buffers to request for heatmap. 96 * The kernel driver will be allocating these buffers for us, 97 * and will provide memory locations to read these from. 98 */ 99 static constexpr size_t NUM_BUFFERS = 3; 100 std::array<const int16_t*, NUM_BUFFERS> mReadLocations; 101 /** 102 * How many buffers to keep for the internal queue. When the internal buffer 103 * exceeds this capacity, oldest frames will be dropped. 104 */ 105 static constexpr size_t MAX_QUEUE_SIZE = 20; 106 std::vector<TouchVideoFrame> mFrames; 107 108 /** 109 * The constructor is private because opening a v4l2 device requires many checks. 110 * To get a new TouchVideoDevice, use 'create' instead. 111 */ 112 explicit TouchVideoDevice(int fd, std::string&& name, std::string&& devicePath, uint32_t height, 113 uint32_t width, 114 const std::array<const int16_t*, NUM_BUFFERS>& readLocations); 115 /** 116 * Read all currently available frames. 117 */ 118 std::vector<TouchVideoFrame> readFrames(); 119 /** 120 * Read a single frame. May return nullopt if no data is currently available for reading. 121 */ 122 std::optional<TouchVideoFrame> readFrame(); 123 }; 124 125 } // namespace android 126 127 #endif // _UI_INPUTFLINGER_TOUCH_VIDEO_DEVICE_H 128