| /* |
| * Copyright (C) 2017 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "HidRawSensorDevice.h" |
| #include "HidRawSensor.h" |
| #include "HidSensorDef.h" |
| |
| #include <utils/Log.h> |
| #include <fcntl.h> |
| #include <linux/input.h> |
| #include <linux/hidraw.h> |
| #include <sys/ioctl.h> |
| |
| #include <set> |
| |
| namespace android { |
| namespace SensorHalExt { |
| |
| using namespace Hid::Sensor::SensorTypeUsage; |
| using namespace Hid::Sensor::PropertyUsage; |
| |
| const std::unordered_set<unsigned int> HidRawSensorDevice::sInterested{ |
| ACCELEROMETER_3D, GYROMETER_3D, COMPASS_3D, CUSTOM}; |
| |
| void HidRawSensorDevice::enableSchedFifoMode() { |
| constexpr int kHidRawSensorPriority = 10; // Matches with sensor service priority |
| struct sched_param param = {0}; |
| param.sched_priority = kHidRawSensorPriority; |
| if (sched_setscheduler(getTid(), SCHED_FIFO | SCHED_RESET_ON_FORK, ¶m) != 0) { |
| ALOGE("Couldn't set SCHED_FIFO for HidRawSensor thread: %s", strerror(errno)); |
| } |
| } |
| |
| sp<HidRawSensorDevice> HidRawSensorDevice::create(const std::string &devName) { |
| sp<HidRawSensorDevice> device(new HidRawSensorDevice(devName)); |
| // offset +1 strong count added by constructor |
| device->decStrong(device.get()); |
| |
| if (device->mValid) { |
| return device; |
| } else { |
| return nullptr; |
| } |
| } |
| |
| HidRawSensorDevice::HidRawSensorDevice(const std::string &devName) |
| : RefBase(), HidRawDevice(devName, sInterested), |
| Thread(false /*canCallJava*/), mValid(false) { |
| // create HidRawSensor objects from digest |
| // HidRawSensor object will take sp<HidRawSensorDevice> as parameter, so increment strong count |
| // to prevent "this" being destructed. |
| this->incStrong(this); |
| |
| if (!HidRawDevice::isValid()) { |
| return; |
| } |
| |
| for (const auto &digest : mDigestVector) { // for each usage - vec<ReportPacket> pair |
| uint32_t usage = static_cast<uint32_t>(digest.fullUsage); |
| sp<HidRawSensor> s(new HidRawSensor(this, usage, digest.packets)); |
| if (s->isValid()) { |
| for (const auto &packet : digest.packets) { |
| if (packet.type == HidParser::REPORT_TYPE_INPUT) { // only used for input mapping |
| mSensors.emplace(packet.id/* report id*/, s); |
| } |
| } |
| } |
| } |
| if (mSensors.size() == 0) { |
| return; |
| } |
| |
| run("HidRawSensor", PRIORITY_URGENT_DISPLAY); |
| enableSchedFifoMode(); |
| mValid = true; |
| } |
| |
| HidRawSensorDevice::~HidRawSensorDevice() { |
| ALOGV("~HidRawSensorDevice %p", this); |
| requestExitAndWait(); |
| ALOGV("~HidRawSensorDevice %p, thread exited", this); |
| } |
| |
| bool HidRawSensorDevice::threadLoop() { |
| ALOGV("Hid Raw Device thread started %p", this); |
| std::vector<uint8_t> buffer; |
| bool ret; |
| uint8_t usageId; |
| |
| while(!Thread::exitPending()) { |
| ret = receiveReport(&usageId, &buffer); |
| if (!ret) { |
| break; |
| } |
| |
| auto i = mSensors.find(usageId); |
| if (i == mSensors.end()) { |
| ALOGW("Input of unknow usage id %u received", usageId); |
| continue; |
| } |
| |
| i->second->handleInput(usageId, buffer); |
| } |
| |
| ALOGI("Hid Raw Device thread ended for %p", this); |
| return false; |
| } |
| |
| BaseSensorVector HidRawSensorDevice::getSensors() const { |
| BaseSensorVector ret; |
| std::set<sp<BaseSensorObject>> set; |
| for (const auto &s : mSensors) { |
| if (set.find(s.second) == set.end()) { |
| ret.push_back(s.second); |
| set.insert(s.second); |
| } |
| } |
| return ret; |
| } |
| |
| } // namespace SensorHalExt |
| } // namespace android |