blob: 08eba31199fbf78dc7b213878a88dec1525d5a9c [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
Prabir Pradhan48108662022-09-09 21:22:04 +000017#pragma once
Siarhei Vishniakou22c88462018-12-13 19:34:53 -080018
Siarhei Vishniakou22c88462018-12-13 19:34:53 -080019#include <android-base/unique_fd.h>
20#include <input/TouchVideoFrame.h>
Siarhei Vishniakou22c88462018-12-13 19:34:53 -080021#include <stdint.h>
Prabir Pradhanda7c00c2019-08-29 14:12:42 -070022#include <array>
23#include <optional>
Siarhei Vishniakou22c88462018-12-13 19:34:53 -080024#include <string>
25#include <vector>
26
27namespace android {
28
29/**
30 * Represents a video device that uses v4l2 api to report touch heatmap data.
31 */
32class TouchVideoDevice {
33public:
34 /**
35 * Create a new TouchVideoDevice for the path provided.
36 * Return nullptr upon failure.
37 */
38 static std::unique_ptr<TouchVideoDevice> create(std::string devicePath);
39 ~TouchVideoDevice();
40
41 bool hasValidFd() const { return mFd.get() != INVALID_FD; }
42 /**
43 * Obtain the file descriptor associated with this video device.
44 * Could be used for adding to epoll.
45 */
46 int getFd() const { return mFd.get(); }
47 /**
48 * Get the name of this video device.
49 */
50 const std::string& getName() const { return mName; }
51 /**
52 * Get the file path of this video device.
53 */
54 const std::string& getPath() const { return mPath; }
55 /**
Siarhei Vishniakou22c88462018-12-13 19:34:53 -080056 * Get the height of the heatmap frame
57 */
58 uint32_t getHeight() const { return mHeight; }
59 /**
Siarhei Vishniakoufda3aee2019-02-15 17:10:53 -060060 * Get the width of the heatmap frame
61 */
62 uint32_t getWidth() const { return mWidth; }
63 /**
Siarhei Vishniakou22c88462018-12-13 19:34:53 -080064 * Direct read of the frame. Stores the frame into internal buffer.
65 * Return the number of frames that were successfully read.
66 *
67 * This function should not be called unless buffer is ready!
68 * This must be checked with select, poll, epoll, or similar api first.
69 * If epoll indicates that there is data ready to read, but this function
70 * returns zero, then it is likely an error occurred.
71 */
72 size_t readAndQueueFrames();
73 /**
74 * Return all of the queued frames, and erase them from the local buffer.
Siarhei Vishniakou100278f2019-02-08 14:03:01 -080075 * The returned frames are in the order that they were received from the
76 * v4l2 device, with the oldest frame at the index 0.
Siarhei Vishniakou22c88462018-12-13 19:34:53 -080077 */
78 std::vector<TouchVideoFrame> consumeFrames();
79 /**
80 * Get string representation of this video device.
81 */
82 std::string dump() const;
83
84private:
85 android::base::unique_fd mFd;
86 std::string mName;
87 std::string mPath;
88
Siarhei Vishniakou22c88462018-12-13 19:34:53 -080089 uint32_t mHeight;
Siarhei Vishniakoufda3aee2019-02-15 17:10:53 -060090 uint32_t mWidth;
Siarhei Vishniakou22c88462018-12-13 19:34:53 -080091
92 static constexpr int INVALID_FD = -1;
93 /**
94 * How many buffers to request for heatmap.
95 * The kernel driver will be allocating these buffers for us,
96 * and will provide memory locations to read these from.
97 */
98 static constexpr size_t NUM_BUFFERS = 3;
99 std::array<const int16_t*, NUM_BUFFERS> mReadLocations;
100 /**
101 * How many buffers to keep for the internal queue. When the internal buffer
102 * exceeds this capacity, oldest frames will be dropped.
103 */
Siarhei Vishniakou487938e2020-07-07 10:58:09 -0500104 static constexpr size_t MAX_QUEUE_SIZE = 20;
Siarhei Vishniakou22c88462018-12-13 19:34:53 -0800105 std::vector<TouchVideoFrame> mFrames;
106
107 /**
108 * The constructor is private because opening a v4l2 device requires many checks.
109 * To get a new TouchVideoDevice, use 'create' instead.
110 */
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700111 explicit TouchVideoDevice(int fd, std::string&& name, std::string&& devicePath, uint32_t height,
112 uint32_t width,
113 const std::array<const int16_t*, NUM_BUFFERS>& readLocations);
Siarhei Vishniakou22c88462018-12-13 19:34:53 -0800114 /**
115 * Read all currently available frames.
116 */
117 std::vector<TouchVideoFrame> readFrames();
118 /**
119 * Read a single frame. May return nullopt if no data is currently available for reading.
120 */
121 std::optional<TouchVideoFrame> readFrame();
122};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700123
Siarhei Vishniakou22c88462018-12-13 19:34:53 -0800124} // namespace android