1 /*
2  * Copyright (C) 2017 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 #include "HidRawSensorDevice.h"
18 #include "HidRawSensor.h"
19 #include "HidSensorDef.h"
20 
21 #include <utils/Log.h>
22 #include <fcntl.h>
23 #include <linux/input.h>
24 #include <linux/hidraw.h>
25 #include <sys/ioctl.h>
26 
27 #include <set>
28 
29 namespace android {
30 namespace SensorHalExt {
31 
32 using namespace Hid::Sensor::SensorTypeUsage;
33 using namespace Hid::Sensor::PropertyUsage;
34 
35 const std::unordered_set<unsigned int> HidRawSensorDevice::sInterested{
36         ACCELEROMETER_3D, GYROMETER_3D, COMPASS_3D, CUSTOM};
37 
create(const std::string & devName)38 sp<HidRawSensorDevice> HidRawSensorDevice::create(const std::string &devName) {
39     sp<HidRawSensorDevice> device(new HidRawSensorDevice(devName));
40     // offset +1 strong count added by constructor
41     device->decStrong(device.get());
42 
43     if (device->mValid) {
44         return device;
45     } else {
46         return nullptr;
47     }
48 }
49 
HidRawSensorDevice(const std::string & devName)50 HidRawSensorDevice::HidRawSensorDevice(const std::string &devName)
51         : RefBase(), HidRawDevice(devName, sInterested),
52           Thread(false /*canCallJava*/), mValid(false) {
53     // create HidRawSensor objects from digest
54     // HidRawSensor object will take sp<HidRawSensorDevice> as parameter, so increment strong count
55     // to prevent "this" being destructed.
56     this->incStrong(this);
57 
58     if (!HidRawDevice::isValid()) {
59         return;
60     }
61 
62     for (const auto &digest : mDigestVector) { // for each usage - vec<ReportPacket> pair
63         uint32_t usage = static_cast<uint32_t>(digest.fullUsage);
64         sp<HidRawSensor> s(new HidRawSensor(this, usage, digest.packets));
65         if (s->isValid()) {
66             for (const auto &packet : digest.packets) {
67                 if (packet.type == HidParser::REPORT_TYPE_INPUT) { // only used for input mapping
68                     mSensors.emplace(packet.id/* report id*/, s);
69                 }
70             }
71         }
72     }
73     if (mSensors.size() == 0) {
74         return;
75     }
76 
77     run("HidRawSensor");
78     mValid = true;
79 }
80 
~HidRawSensorDevice()81 HidRawSensorDevice::~HidRawSensorDevice() {
82     ALOGV("~HidRawSensorDevice %p", this);
83     requestExitAndWait();
84     ALOGV("~HidRawSensorDevice %p, thread exited", this);
85 }
86 
threadLoop()87 bool HidRawSensorDevice::threadLoop() {
88     ALOGV("Hid Raw Device thread started %p", this);
89     std::vector<uint8_t> buffer;
90     bool ret;
91     uint8_t usageId;
92 
93     while(!Thread::exitPending()) {
94         ret = receiveReport(&usageId, &buffer);
95         if (!ret) {
96             break;
97         }
98 
99         auto i = mSensors.find(usageId);
100         if (i == mSensors.end()) {
101             ALOGW("Input of unknow usage id %u received", usageId);
102             continue;
103         }
104 
105         i->second->handleInput(usageId, buffer);
106     }
107 
108     ALOGI("Hid Raw Device thread ended for %p", this);
109     return false;
110 }
111 
getSensors() const112 BaseSensorVector HidRawSensorDevice::getSensors() const {
113     BaseSensorVector ret;
114     std::set<sp<BaseSensorObject>> set;
115     for (const auto &s : mSensors) {
116         if (set.find(s.second) == set.end()) {
117             ret.push_back(s.second);
118             set.insert(s.second);
119         }
120     }
121     return ret;
122 }
123 
124 } // namespace SensorHalExt
125 } // namespace android
126