Home | History | Annotate | Download | only in dynamic_sensor
      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 
     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 
     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 
     81 HidRawSensorDevice::~HidRawSensorDevice() {
     82     ALOGV("~HidRawSensorDevice %p", this);
     83     requestExitAndWait();
     84     ALOGV("~HidRawSensorDevice %p, thread exited", this);
     85 }
     86 
     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 
    112 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