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 29namespace android { 30namespace SensorHalExt { 31 32using namespace Hid::Sensor::SensorTypeUsage; 33using namespace Hid::Sensor::PropertyUsage; 34 35const std::unordered_set<unsigned int> HidRawSensorDevice::sInterested{ 36 ACCELEROMETER_3D, GYROMETER_3D, COMPASS_3D, CUSTOM}; 37 38sp<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 50HidRawSensorDevice::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 81HidRawSensorDevice::~HidRawSensorDevice() { 82 ALOGV("~HidRawSensorDevice %p", this); 83 requestExitAndWait(); 84 ALOGV("~HidRawSensorDevice %p, thread exited", this); 85} 86 87bool 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 112BaseSensorVector 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