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 #include "inputsource.h"
17 #include "defines.h"
18 #include <utils/Log.h>
19
20 #include <fcntl.h>
21 #include <sstream>
22 #include <string.h>
23 #include <unistd.h>
24
25 using namespace com::android::car::keventreader;
26
kevent()27 InputSource::kevent::kevent() {
28 bzero(this, sizeof(*this));
29 }
30
isKeypress() const31 bool InputSource::kevent::isKeypress() const {
32 return type == EV_KEY;
33 }
34
isKeydown() const35 bool InputSource::kevent::isKeydown() const {
36 return isKeypress() && (value == 1);
37 }
38
isKeyup() const39 bool InputSource::kevent::isKeyup() const {
40 return isKeypress() && (value == 0);
41 }
42
InputSource(const char * file)43 InputSource::InputSource(const char* file) : mFilePath(file), mDescriptor(open(file, O_RDONLY)) {}
44
operator bool() const45 InputSource::operator bool() const {
46 return descriptor() >= 0;
47 }
48
descriptor() const49 int InputSource::descriptor() const {
50 return mDescriptor;
51 }
52
read() const53 std::optional<com::android::car::keventreader::KeypressEvent> InputSource::read() const {
54 kevent evt;
55
56 auto cnt = ::read(mDescriptor, &evt, sizeof(evt));
57
58 // the kernel guarantees that we will always be able to read a whole number of events
59 if (cnt < static_cast<decltype(cnt)>(sizeof(evt))) {
60 return std::nullopt;
61 }
62 if (!evt.isKeypress()) {
63 return std::nullopt;
64 }
65
66 ALOGD("input source %s generated code %u (down = %s)",
67 mFilePath.c_str(), evt.code, evt.isKeydown() ? "true" : "false");
68 return com::android::car::keventreader::KeypressEvent(mFilePath, evt.code, evt.isKeydown());
69 }
70
~InputSource()71 InputSource::~InputSource() {
72 if (mDescriptor) ::close(mDescriptor);
73 }
74