Enable wakeup sensors.

SensorService should hold a wakelock till the app reads events from a wakeup sensor. Currently drivers hold a wakelock with a
timeout while delivering events from a wake up sensor like Significant Motion. This hack can be removed now.

Bug: 9774884
Change-Id: If3b5acb99c9cf0cd29012fcfa9d6b04c74133d01
diff --git a/libs/gui/ISensorEventConnection.cpp b/libs/gui/ISensorEventConnection.cpp
index 28fcb53..8f88141 100644
--- a/libs/gui/ISensorEventConnection.cpp
+++ b/libs/gui/ISensorEventConnection.cpp
@@ -34,7 +34,8 @@
     GET_SENSOR_CHANNEL = IBinder::FIRST_CALL_TRANSACTION,
     ENABLE_DISABLE,
     SET_EVENT_RATE,
-    FLUSH_SENSOR
+    FLUSH_SENSOR,
+    DECREASE_WAKE_LOCK_REFCOUNT
 };
 
 class BpSensorEventConnection : public BpInterface<ISensorEventConnection>
@@ -83,6 +84,13 @@
         remote()->transact(FLUSH_SENSOR, data, &reply);
         return reply.readInt32();
     }
+
+    virtual void decreaseWakeLockRefCount() {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISensorEventConnection::getInterfaceDescriptor());
+        remote()->transact(DECREASE_WAKE_LOCK_REFCOUNT, data, &reply, IBinder::FLAG_ONEWAY);
+        return;
+    }
 };
 
 IMPLEMENT_META_INTERFACE(SensorEventConnection, "android.gui.SensorEventConnection");
@@ -125,6 +133,11 @@
             reply->writeInt32(result);
             return NO_ERROR;
         } break;
+        case DECREASE_WAKE_LOCK_REFCOUNT: {
+            CHECK_INTERFACE(ISensorEventConnection, data, reply);
+            decreaseWakeLockRefCount();
+            return NO_ERROR;
+        } break;
     }
     return BBinder::onTransact(code, data, reply, flags);
 }
diff --git a/libs/gui/Sensor.cpp b/libs/gui/Sensor.cpp
index 6f1a3f2..b363411 100644
--- a/libs/gui/Sensor.cpp
+++ b/libs/gui/Sensor.cpp
@@ -32,7 +32,8 @@
 Sensor::Sensor()
     : mHandle(0), mType(0),
       mMinValue(0), mMaxValue(0), mResolution(0),
-      mPower(0), mMinDelay(0), mFifoReservedEventCount(0), mFifoMaxEventCount(0)
+      mPower(0), mMinDelay(0), mFifoReservedEventCount(0), mFifoMaxEventCount(0),
+      mWakeUpSensor(false)
 {
 }
 
@@ -48,6 +49,7 @@
     mResolution = hwSensor->resolution;
     mPower = hwSensor->power;
     mMinDelay = hwSensor->minDelay;
+    mWakeUpSensor = false;
 
     // Set fifo event count zero for older devices which do not support batching. Fused
     // sensors also have their fifo counts set to zero.
@@ -104,6 +106,7 @@
         break;
     case SENSOR_TYPE_PROXIMITY:
         mStringType = SENSOR_STRING_TYPE_PROXIMITY;
+        mWakeUpSensor = true;
         break;
     case SENSOR_TYPE_RELATIVE_HUMIDITY:
         mStringType = SENSOR_STRING_TYPE_RELATIVE_HUMIDITY;
@@ -113,6 +116,7 @@
         break;
     case SENSOR_TYPE_SIGNIFICANT_MOTION:
         mStringType = SENSOR_STRING_TYPE_SIGNIFICANT_MOTION;
+        mWakeUpSensor = true;
         break;
     case SENSOR_TYPE_STEP_COUNTER:
         mStringType = SENSOR_STRING_TYPE_STEP_COUNTER;
@@ -123,14 +127,93 @@
     case SENSOR_TYPE_TEMPERATURE:
         mStringType = SENSOR_STRING_TYPE_TEMPERATURE;
         break;
+    case SENSOR_TYPE_NON_WAKE_UP_PROXIMITY_SENSOR:
+        mStringType = SENSOR_STRING_TYPE_NON_WAKE_UP_PROXIMITY_SENSOR;
+        break;
+    case SENSOR_TYPE_WAKE_UP_ACCELEROMETER:
+        mStringType = SENSOR_STRING_TYPE_WAKE_UP_ACCELEROMETER;
+        mWakeUpSensor = true;
+        break;
+    case SENSOR_TYPE_WAKE_UP_MAGNETIC_FIELD:
+        mStringType = SENSOR_STRING_TYPE_WAKE_UP_MAGNETIC_FIELD;
+        mWakeUpSensor = true;
+        break;
+    case SENSOR_TYPE_WAKE_UP_ORIENTATION:
+        mStringType = SENSOR_STRING_TYPE_WAKE_UP_ORIENTATION;
+        mWakeUpSensor = true;
+        break;
+    case SENSOR_TYPE_WAKE_UP_GYROSCOPE:
+        mStringType = SENSOR_STRING_TYPE_WAKE_UP_GYROSCOPE;
+        mWakeUpSensor = true;
+        break;
+    case SENSOR_TYPE_WAKE_UP_LIGHT:
+        mStringType = SENSOR_STRING_TYPE_WAKE_UP_LIGHT;
+        mWakeUpSensor = true;
+        break;
+    case SENSOR_TYPE_WAKE_UP_PRESSURE:
+        mStringType = SENSOR_STRING_TYPE_WAKE_UP_PRESSURE;
+        mWakeUpSensor = true;
+        break;
+    case SENSOR_TYPE_WAKE_UP_GRAVITY:
+        mStringType = SENSOR_STRING_TYPE_WAKE_UP_GRAVITY;
+        mWakeUpSensor = true;
+        break;
+    case SENSOR_TYPE_WAKE_UP_LINEAR_ACCELERATION:
+        mStringType = SENSOR_STRING_TYPE_WAKE_UP_LINEAR_ACCELERATION;
+        mWakeUpSensor = true;
+        break;
+    case SENSOR_TYPE_WAKE_UP_ROTATION_VECTOR:
+        mStringType = SENSOR_STRING_TYPE_WAKE_UP_ROTATION_VECTOR;
+        mWakeUpSensor = true;
+        break;
+    case SENSOR_TYPE_WAKE_UP_RELATIVE_HUMIDITY:
+        mStringType = SENSOR_STRING_TYPE_WAKE_UP_RELATIVE_HUMIDITY;
+        mWakeUpSensor = true;
+        break;
+    case SENSOR_TYPE_WAKE_UP_AMBIENT_TEMPERATURE:
+        mStringType = SENSOR_STRING_TYPE_WAKE_UP_AMBIENT_TEMPERATURE;
+        mWakeUpSensor = true;
+        break;
+    case SENSOR_TYPE_WAKE_UP_MAGNETIC_FIELD_UNCALIBRATED:
+        mStringType = SENSOR_STRING_TYPE_WAKE_UP_MAGNETIC_FIELD_UNCALIBRATED;
+        mWakeUpSensor = true;
+        break;
+    case SENSOR_TYPE_WAKE_UP_GAME_ROTATION_VECTOR:
+        mStringType = SENSOR_STRING_TYPE_WAKE_UP_GAME_ROTATION_VECTOR;
+        mWakeUpSensor = true;
+        break;
+    case SENSOR_TYPE_WAKE_UP_GYROSCOPE_UNCALIBRATED:
+        mStringType = SENSOR_STRING_TYPE_WAKE_UP_GYROSCOPE_UNCALIBRATED;
+        mWakeUpSensor = true;
+        break;
+    case SENSOR_TYPE_WAKE_UP_STEP_DETECTOR:
+        mStringType = SENSOR_STRING_TYPE_WAKE_UP_STEP_DETECTOR;
+        mWakeUpSensor = true;
+        break;
+    case SENSOR_TYPE_WAKE_UP_STEP_COUNTER:
+        mStringType = SENSOR_STRING_TYPE_WAKE_UP_STEP_COUNTER;
+        mWakeUpSensor = true;
+        break;
+    case SENSOR_TYPE_WAKE_UP_GEOMAGNETIC_ROTATION_VECTOR:
+        mStringType = SENSOR_STRING_TYPE_WAKE_UP_GEOMAGNETIC_ROTATION_VECTOR;
+        mWakeUpSensor = true;
+        break;
+    case SENSOR_TYPE_WAKE_UP_HEART_RATE:
+        mStringType = SENSOR_STRING_TYPE_WAKE_UP_HEART_RATE;
+        mRequiredPermission = SENSOR_PERMISSION_BODY_SENSORS;
+        mWakeUpSensor = true;
+        break;
     default:
-        // Only pipe the stringType and requiredPermission for custom sensors.
+        // Only pipe the stringType, requiredPermission and flags for custom sensors.
         if (halVersion >= SENSORS_DEVICE_API_VERSION_1_2 && hwSensor->stringType) {
             mStringType = hwSensor->stringType;
         }
         if (halVersion >= SENSORS_DEVICE_API_VERSION_1_2 && hwSensor->requiredPermission) {
             mRequiredPermission = hwSensor->requiredPermission;
         }
+        if (halVersion >= SENSORS_DEVICE_API_VERSION_1_3) {
+            mWakeUpSensor = hwSensor->flags & SENSOR_FLAG_WAKE_UP;
+        }
         break;
     }
 }
@@ -199,6 +282,10 @@
     return mRequiredPermission;
 }
 
+bool Sensor::isWakeUpSensor() const {
+    return mWakeUpSensor;
+}
+
 size_t Sensor::getFlattenedSize() const
 {
     size_t fixedSize =
diff --git a/libs/gui/SensorEventQueue.cpp b/libs/gui/SensorEventQueue.cpp
index c365671..c2eaf4e 100644
--- a/libs/gui/SensorEventQueue.cpp
+++ b/libs/gui/SensorEventQueue.cpp
@@ -144,6 +144,15 @@
     return mSensorEventConnection->setEventRate(sensor->getHandle(), ns);
 }
 
+void SensorEventQueue::sendAck(const ASensorEvent* events, int count) {
+    for (int i = 0; i < count; ++i) {
+        if (events[i].flags & WAKE_UP_SENSOR_EVENT_NEEDS_ACK) {
+            mSensorEventConnection->decreaseWakeLockRefCount();
+        }
+    }
+    return;
+}
+
 // ----------------------------------------------------------------------------
 }; // namespace android