Home | History | Annotate | Download | only in sensorhal
      1 /*
      2  * Copyright (C) 2015 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 #ifndef HUB_CONNECTION_H_
     18 
     19 #define HUB_CONNECTION_H_
     20 
     21 #include <sys/types.h>
     22 #include <sys/stat.h>
     23 #include <fcntl.h>
     24 #include <poll.h>
     25 
     26 #include <utils/Errors.h>
     27 #include <utils/Mutex.h>
     28 #include <utils/Thread.h>
     29 
     30 #include <list>
     31 
     32 #include "activityeventhandler.h"
     33 #include "directchannel.h"
     34 #include "eventnums.h"
     35 #include "halIntf.h"
     36 #include "hubdefs.h"
     37 #include "ring.h"
     38 
     39 #ifdef USE_SENSORSERVICE_TO_GET_FIFO
     40 #include <thread>
     41 #endif
     42 #include <unordered_map>
     43 
     44 #define WAKELOCK_NAME "sensorHal"
     45 
     46 #define ACCEL_BIAS_TAG     "accel"
     47 #define ACCEL_SW_BIAS_TAG  "accel_sw"
     48 #define GYRO_BIAS_TAG      "gyro"
     49 #define GYRO_OTC_DATA_TAG  "gyro_otc"
     50 #define GYRO_SW_BIAS_TAG   "gyro_sw"
     51 #define MAG_BIAS_TAG       "mag"
     52 
     53 #define MAX_ALTERNATES     2
     54 
     55 namespace android {
     56 
     57 struct HubConnection : public Thread {
     58     static HubConnection *getInstance();
     59 
     60     status_t initCheck() const;
     61 
     62     enum ProximitySensorType {
     63         PROXIMITY_UNKNOWN,
     64         PROXIMITY_ROHM,
     65         PROXIMITY_AMS,
     66     };
     67 
     68     // Blocks until it can return a status
     69     status_t getAliveCheck();
     70 
     71     virtual bool threadLoop();
     72 
     73     void queueActivate(int handle, bool enable);
     74     void queueSetDelay(int handle, nsecs_t delayNs);
     75     void queueBatch(int handle, nsecs_t sampling_period_ns,
     76             nsecs_t max_report_latency_ns);
     77     void queueFlush(int handle);
     78     void queueData(int handle, void *data, size_t length);
     79 
     80     void setOperationParameter(const additional_info_event_t &info);
     81 
     82     void releaseWakeLockIfAppropriate();
     83 
     84     //TODO: factor out event ring buffer functionality into a separate class
     85     ssize_t read(sensors_event_t *ev, size_t size);
     86     ssize_t write(const sensors_event_t *ev, size_t n);
     87 
     88     void setActivityCallback(ActivityEventHandler *eventHandler);
     89 
     90     void saveSensorSettings() const;
     91 
     92     void setRawScale(float scaleAccel, float scaleMag) {
     93         mScaleAccel = scaleAccel;
     94         mScaleMag = scaleMag;
     95     }
     96 
     97     void setLeftyMode(bool enable);
     98 
     99 protected:
    100     HubConnection();
    101     virtual ~HubConnection();
    102 
    103     virtual void onFirstRef();
    104 
    105 private:
    106     typedef uint32_t rate_q10_t;  // q10 means lower 10 bits are for fractions
    107 
    108     bool mWakelockHeld;
    109     int32_t mWakeEventCount;
    110 
    111     void protectIfWakeEventLocked(int32_t sensor);
    112     ssize_t decrementIfWakeEventLocked(int32_t sensor);
    113 
    114     static inline uint64_t period_ns_to_frequency_q10(nsecs_t period_ns) {
    115         return 1024000000000ULL / period_ns;
    116     }
    117 
    118     static inline nsecs_t frequency_q10_to_period_ns(uint64_t frequency_q10) {
    119         if (frequency_q10)
    120             return 1024000000000LL / frequency_q10;
    121         else
    122             return (nsecs_t)0;
    123     }
    124 
    125     static inline uint64_t frequency_to_frequency_q10(float frequency) {
    126         return period_ns_to_frequency_q10(static_cast<nsecs_t>(1e9f/frequency));
    127     }
    128 
    129     enum
    130     {
    131         CONFIG_CMD_DISABLE      = 0,
    132         CONFIG_CMD_ENABLE       = 1,
    133         CONFIG_CMD_FLUSH        = 2,
    134         CONFIG_CMD_CFG_DATA     = 3,
    135         CONFIG_CMD_CALIBRATE    = 4,
    136     };
    137 
    138     struct ConfigCmd
    139     {
    140         uint32_t evtType;
    141         uint64_t latency;
    142         rate_q10_t rate;
    143         uint8_t sensorType;
    144         uint8_t cmd;
    145         uint16_t flags;
    146         uint8_t data[];
    147     } __attribute__((packed));
    148 
    149     struct MsgCmd
    150     {
    151         uint32_t evtType;
    152         struct HostHubRawPacket msg;
    153     } __attribute__((packed));
    154 
    155     struct LeftyState
    156     {
    157         bool accel; // Process wrist-aware accel samples as lefty mode
    158         bool gyro; // Process wrist-aware gyro samples as lefty mode
    159         bool hub; // Sensor hub is currently operating in lefty mode
    160     };
    161 
    162     struct Flush
    163     {
    164         int handle;
    165         uint8_t count;
    166 
    167         // Used to synchronize the transition in and out of
    168         // lefty mode between nanohub and the AP.
    169         bool internal;
    170     };
    171 
    172     struct SensorState {
    173         uint64_t latency;
    174         uint64_t lastTimestamp;
    175         uint64_t desiredTSample;
    176         rate_q10_t rate;
    177         uint8_t sensorType;
    178         uint8_t primary;
    179         uint8_t alt[MAX_ALTERNATES];
    180         bool enable;
    181     };
    182 
    183     struct FirstSample
    184     {
    185         uint8_t numSamples;
    186         uint8_t numFlushes;
    187         uint8_t highAccuracy : 1;
    188         uint8_t biasPresent : 1;
    189         uint8_t biasSample : 6;
    190         uint8_t pad;
    191     };
    192 
    193     struct RawThreeAxisSample
    194     {
    195         uint32_t deltaTime;
    196         int16_t ix, iy, iz;
    197     } __attribute__((packed));
    198 
    199     struct ThreeAxisSample
    200     {
    201         uint32_t deltaTime;
    202         float x, y, z;
    203     } __attribute__((packed));
    204 
    205     struct OneAxisSample
    206     {
    207         uint32_t deltaTime;
    208         union
    209         {
    210             float fdata;
    211             uint32_t idata;
    212         };
    213     } __attribute__((packed));
    214 
    215     // The following structure should match struct HostIntfDataBuffer found in
    216     // firmware/inc/hostIntf.h
    217     struct nAxisEvent
    218     {
    219         uint32_t evtType;
    220         union
    221         {
    222             struct
    223             {
    224                 uint64_t referenceTime;
    225                 union
    226                 {
    227                     struct FirstSample firstSample;
    228                     struct OneAxisSample oneSamples[];
    229                     struct RawThreeAxisSample rawThreeSamples[];
    230                     struct ThreeAxisSample threeSamples[];
    231                 };
    232             };
    233             uint8_t buffer[];
    234         };
    235     } __attribute__((packed));
    236 
    237     static Mutex sInstanceLock;
    238     static HubConnection *sInstance;
    239 
    240     // This lock is used for synchronization between the write thread (from
    241     // sensorservice) and the read thread polling from the nanohub driver.
    242     Mutex mLock;
    243 
    244     RingBuffer mRing;
    245     int32_t mWriteFailures;
    246 
    247     ActivityEventHandler *mActivityEventHandler;
    248 
    249     float mMagBias[3];
    250     uint8_t mMagAccuracy;
    251     uint8_t mMagAccuracyRestore;
    252 
    253     float mGyroBias[3], mAccelBias[3];
    254     GyroOtcData mGyroOtcData;
    255 
    256     float mScaleAccel, mScaleMag;
    257 
    258     LeftyState mLefty;
    259 
    260     SensorState mSensorState[NUM_COMMS_SENSORS_PLUS_1];
    261     std::list<struct Flush> mFlushesPending[NUM_COMMS_SENSORS_PLUS_1];
    262 
    263     uint64_t mStepCounterOffset;
    264     uint64_t mLastStepCount;
    265 
    266     int mFd;
    267     int mInotifyPollIndex;
    268     struct pollfd mPollFds[4];
    269     int mNumPollFds;
    270 
    271     sensors_event_t *initEv(sensors_event_t *ev, uint64_t timestamp, uint32_t type, uint32_t sensor);
    272     uint8_t magAccuracyUpdate(sensors_vec_t *sv);
    273     void processSample(uint64_t timestamp, uint32_t type, uint32_t sensor, struct OneAxisSample *sample, bool highAccuracy);
    274     void processSample(uint64_t timestamp, uint32_t type, uint32_t sensor, struct RawThreeAxisSample *sample, bool highAccuracy);
    275     void processSample(uint64_t timestamp, uint32_t type, uint32_t sensor, struct ThreeAxisSample *sample, bool highAccuracy);
    276     void postOsLog(uint8_t *buf, ssize_t len);
    277     void processAppData(uint8_t *buf, ssize_t len);
    278     ssize_t processBuf(uint8_t *buf, size_t len);
    279 
    280     inline bool isValidHandle(int handle) {
    281         return handle >= 0
    282             && handle < NUM_COMMS_SENSORS_PLUS_1
    283             && mSensorState[handle].sensorType;
    284     }
    285 
    286     ssize_t sendCmd(const void *buf, size_t count);
    287     void initConfigCmd(struct ConfigCmd *cmd, int handle);
    288 
    289     void queueFlushInternal(int handle, bool internal);
    290 
    291     void queueDataInternal(int handle, void *data, size_t length);
    292 
    293     void discardInotifyEvent();
    294     void waitOnNanohubLock();
    295 
    296     void initNanohubLock();
    297 
    298     void restoreSensorState();
    299     void sendCalibrationOffsets();
    300 
    301 #ifdef USE_SENSORSERVICE_TO_GET_FIFO
    302     // Enable SCHED_FIFO priority for main thread
    303     std::thread mEnableSchedFifoThread;
    304 #endif
    305     static void enableSchedFifoMode(sp<HubConnection> hub);
    306 
    307 #ifdef LID_STATE_REPORTING_ENABLED
    308     int mUinputFd;
    309 
    310     status_t initializeUinputNode();
    311     void sendFolioEvent(int32_t data);
    312 #endif  // LID_STATE_REPORTING_ENABLED
    313 
    314 #ifdef USB_MAG_BIAS_REPORTING_ENABLED
    315     int mMagBiasPollIndex;
    316     float mUsbMagBias;
    317 
    318     void queueUsbMagBias();
    319 #endif  // USB_MAG_BIAS_REPORTING_ENABLED
    320 
    321 #ifdef DOUBLE_TOUCH_ENABLED
    322     int mDoubleTouchPollIndex;
    323 #endif  // DOUBLE_TOUCH_ENABLED
    324 
    325     // Direct report functions
    326 public:
    327     int addDirectChannel(const struct sensors_direct_mem_t *mem);
    328     int removeDirectChannel(int channel_handle);
    329     int configDirectReport(int sensor_handle, int channel_handle, int rate_level);
    330     bool isDirectReportSupported() const;
    331 private:
    332     void sendDirectReportEvent(const sensors_event_t *nev, size_t n);
    333     void mergeDirectReportRequest(struct ConfigCmd *cmd, int handle);
    334     bool isSampleIntervalSatisfied(int handle, uint64_t timestamp);
    335     void updateSampleRate(int handle, int reason);
    336 #ifdef DIRECT_REPORT_ENABLED
    337     int stopAllDirectReportOnChannel(
    338             int channel_handle, std::vector<int32_t> *unstoppedSensors);
    339     uint64_t rateLevelToDeviceSamplingPeriodNs(int handle, int rateLevel) const;
    340     inline static bool intervalLargeEnough(uint64_t actual, uint64_t desired) {
    341         return (actual + (actual >> 4)) >= desired; // >= 94.11% of desired
    342     }
    343 
    344     struct DirectChannelTimingInfo{
    345         uint64_t lastTimestamp;
    346         int rateLevel;
    347     };
    348     Mutex mDirectChannelLock;
    349     //sensor_handle=>(channel_handle => DirectChannelTimingInfo)
    350     std::unordered_map<int32_t,
    351             std::unordered_map<int32_t, DirectChannelTimingInfo> > mSensorToChannel;
    352     //channel_handle=>ptr of Channel obj
    353     std::unordered_map<int32_t, std::unique_ptr<DirectChannelBase>> mDirectChannel;
    354     int32_t mDirectChannelHandle;
    355 #endif
    356 
    357     DISALLOW_EVIL_CONSTRUCTORS(HubConnection);
    358 };
    359 
    360 }  // namespace android
    361 
    362 #endif  // HUB_CONNECTION_H_
    363