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