blob: 7ff265330f094050947057321fe68e0685a53692 [file] [log] [blame]
Siarhei Vishniakou22c88462018-12-13 19:34:53 -08001/*
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 _INPUTFLINGER_TOUCH_VIDEO_DEVICE_H
18#define _INPUTFLINGER_TOUCH_VIDEO_DEVICE_H
19
20#include <array>
21#include <android-base/unique_fd.h>
22#include <input/TouchVideoFrame.h>
23#include <optional>
24#include <stdint.h>
25#include <string>
26#include <vector>
27
28namespace android {
29
30/**
31 * Represents a video device that uses v4l2 api to report touch heatmap data.
32 */
33class TouchVideoDevice {
34public:
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
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 */
47 int getFd() const { return mFd.get(); }
48 /**
49 * Get the name of this video device.
50 */
51 const std::string& getName() const { return mName; }
52 /**
53 * Get the file path of this video device.
54 */
55 const std::string& getPath() const { return mPath; }
56 /**
57 * Get the width of the heatmap frame
58 */
59 uint32_t getWidth() const { return mWidth; }
60 /**
61 * Get the height of the heatmap frame
62 */
63 uint32_t getHeight() const { return mHeight; }
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 */
77 std::vector<TouchVideoFrame> consumeFrames();
78 /**
79 * Get string representation of this video device.
80 */
81 std::string dump() const;
82
83private:
84 android::base::unique_fd mFd;
85 std::string mName;
86 std::string mPath;
87
88 uint32_t mWidth;
89 uint32_t mHeight;
90
91 static constexpr int INVALID_FD = -1;
92 /**
93 * How many buffers to request for heatmap.
94 * The kernel driver will be allocating these buffers for us,
95 * and will provide memory locations to read these from.
96 */
97 static constexpr size_t NUM_BUFFERS = 3;
98 std::array<const int16_t*, NUM_BUFFERS> mReadLocations;
99 /**
100 * How many buffers to keep for the internal queue. When the internal buffer
101 * exceeds this capacity, oldest frames will be dropped.
102 */
103 static constexpr size_t MAX_QUEUE_SIZE = 10;
104 std::vector<TouchVideoFrame> mFrames;
105
106 /**
107 * The constructor is private because opening a v4l2 device requires many checks.
108 * To get a new TouchVideoDevice, use 'create' instead.
109 */
110 explicit TouchVideoDevice(int fd, std::string&& name, std::string&& devicePath,
111 uint32_t width, uint32_t height,
112 const std::array<const int16_t*, NUM_BUFFERS>& readLocations);
113 /**
114 * Read all currently available frames.
115 */
116 std::vector<TouchVideoFrame> readFrames();
117 /**
118 * Read a single frame. May return nullopt if no data is currently available for reading.
119 */
120 std::optional<TouchVideoFrame> readFrame();
121};
122} // namespace android
123#endif //_INPUTFLINGER_TOUCH_VIDEO_DEVICE_H