sensors: mpu6515: grab wakelock on significant motion event

The kernel sensor driver grabs a half second wakelock to allow time
for this HAL to read the significant motion event from the kernel and
grab its own wakelock.  The HAL holds the wakelock until Sensor
Services calls poll() again, assuring that Sensor Services has
read the SMD event and will have grabbed its own wakelock.

Bug: 16540661
Change-Id: I1c88cd9386a9f711e6cba81a14539b835f4e7414
diff --git a/6515/libsensors_iio/Android.mk b/6515/libsensors_iio/Android.mk
index 94e03f1..7ae62cd 100755
--- a/6515/libsensors_iio/Android.mk
+++ b/6515/libsensors_iio/Android.mk
@@ -153,6 +153,7 @@
 LOCAL_SHARED_LIBRARIES += libdl
 LOCAL_SHARED_LIBRARIES += liblog
 LOCAL_SHARED_LIBRARIES += libmllite
+LOCAL_SHARED_LIBRARIES += libhardware_legacy
 include $(BUILD_SHARED_LIBRARY)
 
 include $(CLEAR_VARS)
diff --git a/6515/libsensors_iio/sensors_mpl.cpp b/6515/libsensors_iio/sensors_mpl.cpp
index 2df1a8b..c2a36f4 100755
--- a/6515/libsensors_iio/sensors_mpl.cpp
+++ b/6515/libsensors_iio/sensors_mpl.cpp
@@ -16,6 +16,7 @@
 
 #define FUNC_LOG LOGV("%s", __PRETTY_FUNCTION__)
 
+#include <hardware_legacy/power.h>
 #include <hardware/sensors.h>
 #include <fcntl.h>
 #include <errno.h>
@@ -61,6 +62,9 @@
 struct simplehead *headp;
 static pthread_mutex_t flush_handles_mutex = PTHREAD_MUTEX_INITIALIZER;
 
+static const char *smdWakelockStr = "significant motion";
+static pthread_mutex_t mSMDWakelockMutex = PTHREAD_MUTEX_INITIALIZER;
+
 static struct sensor_t sSensorList[LOCAL_SENSORS];
 static int sensors = (sizeof(sSensorList) / sizeof(sensor_t));
 
@@ -121,6 +125,10 @@
     struct pollfd mPollFds[numFds];
     SensorBase *mSensor;
     CompassSensor *mCompassSensor;
+
+    /* Significant Motion wakelock support */
+    unsigned long mSMDEventsPending;
+
 };
 
 /******************************************************************************/
@@ -132,6 +140,9 @@
     mCompassSensor = new CompassSensor();
     MPLSensor *mplSensor = new MPLSensor(mCompassSensor);
 
+    /* No significant motion events pending yet */
+    mSMDEventsPending = 0;
+
    /* For Vendor-defined Accel Calibration File Load
     * Use the Following Constructor and Pass Your Load Cal File Function
     * 
@@ -197,6 +208,16 @@
     int nbEvents = 0;
     int nb, polltime = -1;
 
+
+    pthread_mutex_lock(&mSMDWakelockMutex);
+    if (mSMDEventsPending) {
+        mSMDEventsPending--;
+        /* If there are no more events pending, release our wakelock */
+        if (!mSMDEventsPending)
+            release_wake_lock(smdWakelockStr);
+    }
+    pthread_mutex_unlock(&mSMDWakelockMutex);
+
     struct handle_entry *handle_element;
     pthread_mutex_lock(&flush_handles_mutex);
     if (!SIMPLEQ_EMPTY(&pending_flush_items_head)) {
@@ -243,9 +264,21 @@
                     nb = ((MPLSensor*) mSensor)->
                                     readDmpSignificantMotionEvents(data, count);
                     mPollFds[i].revents = 0;
-                    count -= nb;
-                    nbEvents += nb;
-                    data += nb; 
+                    if (nb) {
+                        pthread_mutex_lock(&mSMDWakelockMutex);
+                        /* if mSMDEventsPending != 0, the wakelock is already held */
+                        if (!mSMDEventsPending) {
+                            /* Hold wakelock until Sensor Services reads event */
+                            acquire_wake_lock(PARTIAL_WAKE_LOCK, smdWakelockStr);
+                            LOGI_IF(1, "HAL: grabbed %s wakelock", smdWakelockStr);
+                        }
+                        mSMDEventsPending++;
+                        pthread_mutex_unlock(&mSMDWakelockMutex);
+
+                        count -= nb;
+                        nbEvents += nb;
+                        data += nb;
+                    }
                 } else if (i == dmpPed) {
                     nb = ((MPLSensor*) mSensor)->readDmpPedometerEvents(
                             data, count, ID_P, 0);