split libsensor our of libgui 

Test: compile & run
Bug: treble cleanup
Change-Id: I5b2c2a14f7d3b364d25695cf0901c5b08cfb0fc9
diff --git a/libs/sensor/Android.bp b/libs/sensor/Android.bp
new file mode 100644
index 0000000..171a627
--- /dev/null
+++ b/libs/sensor/Android.bp
@@ -0,0 +1,61 @@
+// Copyright 2010 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_library_shared {
+    name: "libsensor",
+
+    clang: true,
+    cppflags: [
+        "-Weverything",
+        "-Werror",
+
+        // The static constructors and destructors in this library have not been noted to
+        // introduce significant overheads
+        "-Wno-exit-time-destructors",
+        "-Wno-global-constructors",
+
+        // We only care about compiling as C++14
+        "-Wno-c++98-compat-pedantic",
+
+        // android/sensors.h uses nested anonymous unions and anonymous structs
+        "-Wno-nested-anon-types",
+        "-Wno-gnu-anonymous-struct",
+
+        // Don't warn about struct padding
+        "-Wno-padded",
+    ],
+
+    srcs: [
+        "BitTube.cpp",
+        "ISensorEventConnection.cpp",
+        "ISensorServer.cpp",
+        "Sensor.cpp",
+        "SensorEventQueue.cpp",
+        "SensorManager.cpp",
+    ],
+
+    shared_libs: [
+        "libbinder",
+        "libcutils",
+        "libutils",
+        "liblog",
+        "libhardware",
+    ],
+
+    export_include_dirs: ["include"],
+
+    export_shared_lib_headers: ["libbinder", "libhardware"],
+}
+
+subdirs = ["tests"]
diff --git a/libs/sensor/BitTube.cpp b/libs/sensor/BitTube.cpp
new file mode 100644
index 0000000..93555c8
--- /dev/null
+++ b/libs/sensor/BitTube.cpp
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sensor/BitTube.h>
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <binder/Parcel.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+// Socket buffer size.  The default is typically about 128KB, which is much larger than
+// we really need.  So we make it smaller.
+static const size_t DEFAULT_SOCKET_BUFFER_SIZE = 4 * 1024;
+
+
+BitTube::BitTube()
+    : mSendFd(-1), mReceiveFd(-1)
+{
+    init(DEFAULT_SOCKET_BUFFER_SIZE, DEFAULT_SOCKET_BUFFER_SIZE);
+}
+
+BitTube::BitTube(size_t bufsize)
+    : mSendFd(-1), mReceiveFd(-1)
+{
+    init(bufsize, bufsize);
+}
+
+BitTube::BitTube(const Parcel& data)
+    : mSendFd(-1), mReceiveFd(-1)
+{
+    mReceiveFd = dup(data.readFileDescriptor());
+    if (mReceiveFd < 0) {
+        mReceiveFd = -errno;
+        ALOGE("BitTube(Parcel): can't dup filedescriptor (%s)",
+                strerror(-mReceiveFd));
+    }
+}
+
+BitTube::~BitTube()
+{
+    if (mSendFd >= 0)
+        close(mSendFd);
+
+    if (mReceiveFd >= 0)
+        close(mReceiveFd);
+}
+
+void BitTube::init(size_t rcvbuf, size_t sndbuf) {
+    int sockets[2];
+    if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets) == 0) {
+        size_t size = DEFAULT_SOCKET_BUFFER_SIZE;
+        setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf));
+        setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf));
+        // sine we don't use the "return channel", we keep it small...
+        setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
+        setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
+        fcntl(sockets[0], F_SETFL, O_NONBLOCK);
+        fcntl(sockets[1], F_SETFL, O_NONBLOCK);
+        mReceiveFd = sockets[0];
+        mSendFd = sockets[1];
+    } else {
+        mReceiveFd = -errno;
+        ALOGE("BitTube: pipe creation failed (%s)", strerror(-mReceiveFd));
+    }
+}
+
+status_t BitTube::initCheck() const
+{
+    if (mReceiveFd < 0) {
+        return status_t(mReceiveFd);
+    }
+    return NO_ERROR;
+}
+
+int BitTube::getFd() const
+{
+    return mReceiveFd;
+}
+
+int BitTube::getSendFd() const
+{
+    return mSendFd;
+}
+
+ssize_t BitTube::write(void const* vaddr, size_t size)
+{
+    ssize_t err, len;
+    do {
+        len = ::send(mSendFd, vaddr, size, MSG_DONTWAIT | MSG_NOSIGNAL);
+        // cannot return less than size, since we're using SOCK_SEQPACKET
+        err = len < 0 ? errno : 0;
+    } while (err == EINTR);
+    return err == 0 ? len : -err;
+}
+
+ssize_t BitTube::read(void* vaddr, size_t size)
+{
+    ssize_t err, len;
+    do {
+        len = ::recv(mReceiveFd, vaddr, size, MSG_DONTWAIT);
+        err = len < 0 ? errno : 0;
+    } while (err == EINTR);
+    if (err == EAGAIN || err == EWOULDBLOCK) {
+        // EAGAIN means that we have non-blocking I/O but there was
+        // no data to be read. Nothing the client should care about.
+        return 0;
+    }
+    return err == 0 ? len : -err;
+}
+
+status_t BitTube::writeToParcel(Parcel* reply) const
+{
+    if (mReceiveFd < 0)
+        return -EINVAL;
+
+    status_t result = reply->writeDupFileDescriptor(mReceiveFd);
+    close(mReceiveFd);
+    mReceiveFd = -1;
+    return result;
+}
+
+
+ssize_t BitTube::sendObjects(const sp<BitTube>& tube,
+        void const* events, size_t count, size_t objSize)
+{
+    const char* vaddr = reinterpret_cast<const char*>(events);
+    ssize_t size = tube->write(vaddr, count*objSize);
+
+    // should never happen because of SOCK_SEQPACKET
+    LOG_ALWAYS_FATAL_IF((size >= 0) && (size % static_cast<ssize_t>(objSize)),
+            "BitTube::sendObjects(count=%zu, size=%zu), res=%zd (partial events were sent!)",
+            count, objSize, size);
+
+    //ALOGE_IF(size<0, "error %d sending %d events", size, count);
+    return size < 0 ? size : size / static_cast<ssize_t>(objSize);
+}
+
+ssize_t BitTube::recvObjects(const sp<BitTube>& tube,
+        void* events, size_t count, size_t objSize)
+{
+    char* vaddr = reinterpret_cast<char*>(events);
+    ssize_t size = tube->read(vaddr, count*objSize);
+
+    // should never happen because of SOCK_SEQPACKET
+    LOG_ALWAYS_FATAL_IF((size >= 0) && (size % static_cast<ssize_t>(objSize)),
+            "BitTube::recvObjects(count=%zu, size=%zu), res=%zd (partial events were received!)",
+            count, objSize, size);
+
+    //ALOGE_IF(size<0, "error %d receiving %d events", size, count);
+    return size < 0 ? size : size / static_cast<ssize_t>(objSize);
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/sensor/ISensorEventConnection.cpp b/libs/sensor/ISensorEventConnection.cpp
new file mode 100644
index 0000000..8a3a623
--- /dev/null
+++ b/libs/sensor/ISensorEventConnection.cpp
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sensor/ISensorEventConnection.h>
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/Timers.h>
+
+#include <binder/Parcel.h>
+#include <binder/IInterface.h>
+
+#include <sensor/BitTube.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+enum {
+    GET_SENSOR_CHANNEL = IBinder::FIRST_CALL_TRANSACTION,
+    ENABLE_DISABLE,
+    SET_EVENT_RATE,
+    FLUSH_SENSOR,
+    CONFIGURE_CHANNEL
+};
+
+class BpSensorEventConnection : public BpInterface<ISensorEventConnection>
+{
+public:
+    explicit BpSensorEventConnection(const sp<IBinder>& impl)
+        : BpInterface<ISensorEventConnection>(impl)
+    {
+    }
+
+    virtual ~BpSensorEventConnection();
+
+    virtual sp<BitTube> getSensorChannel() const
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISensorEventConnection::getInterfaceDescriptor());
+        remote()->transact(GET_SENSOR_CHANNEL, data, &reply);
+        return new BitTube(reply);
+    }
+
+    virtual status_t enableDisable(int handle, bool enabled, nsecs_t samplingPeriodNs,
+                                   nsecs_t maxBatchReportLatencyNs, int reservedFlags)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISensorEventConnection::getInterfaceDescriptor());
+        data.writeInt32(handle);
+        data.writeInt32(enabled);
+        data.writeInt64(samplingPeriodNs);
+        data.writeInt64(maxBatchReportLatencyNs);
+        data.writeInt32(reservedFlags);
+        remote()->transact(ENABLE_DISABLE, data, &reply);
+        return reply.readInt32();
+    }
+
+    virtual status_t setEventRate(int handle, nsecs_t ns)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISensorEventConnection::getInterfaceDescriptor());
+        data.writeInt32(handle);
+        data.writeInt64(ns);
+        remote()->transact(SET_EVENT_RATE, data, &reply);
+        return reply.readInt32();
+    }
+
+    virtual status_t flush() {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISensorEventConnection::getInterfaceDescriptor());
+        remote()->transact(FLUSH_SENSOR, data, &reply);
+        return reply.readInt32();
+    }
+
+    virtual int32_t configureChannel(int32_t handle, int32_t rateLevel) {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISensorEventConnection::getInterfaceDescriptor());
+        data.writeInt32(handle);
+        data.writeInt32(rateLevel);
+        remote()->transact(CONFIGURE_CHANNEL, data, &reply);
+        return reply.readInt32();
+    }
+};
+
+// Out-of-line virtual method definition to trigger vtable emission in this
+// translation unit (see clang warning -Wweak-vtables)
+BpSensorEventConnection::~BpSensorEventConnection() {}
+
+IMPLEMENT_META_INTERFACE(SensorEventConnection, "android.gui.SensorEventConnection");
+
+// ----------------------------------------------------------------------------
+
+status_t BnSensorEventConnection::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code) {
+        case GET_SENSOR_CHANNEL: {
+            CHECK_INTERFACE(ISensorEventConnection, data, reply);
+            sp<BitTube> channel(getSensorChannel());
+            channel->writeToParcel(reply);
+            return NO_ERROR;
+        }
+        case ENABLE_DISABLE: {
+            CHECK_INTERFACE(ISensorEventConnection, data, reply);
+            int handle = data.readInt32();
+            int enabled = data.readInt32();
+            nsecs_t samplingPeriodNs = data.readInt64();
+            nsecs_t maxBatchReportLatencyNs = data.readInt64();
+            int reservedFlags = data.readInt32();
+            status_t result = enableDisable(handle, enabled, samplingPeriodNs,
+                                            maxBatchReportLatencyNs, reservedFlags);
+            reply->writeInt32(result);
+            return NO_ERROR;
+        }
+        case SET_EVENT_RATE: {
+            CHECK_INTERFACE(ISensorEventConnection, data, reply);
+            int handle = data.readInt32();
+            nsecs_t ns = data.readInt64();
+            status_t result = setEventRate(handle, ns);
+            reply->writeInt32(result);
+            return NO_ERROR;
+        }
+        case FLUSH_SENSOR: {
+            CHECK_INTERFACE(ISensorEventConnection, data, reply);
+            status_t result = flush();
+            reply->writeInt32(result);
+            return NO_ERROR;
+        }
+        case CONFIGURE_CHANNEL: {
+            CHECK_INTERFACE(ISensorEventConnection, data, reply);
+            int handle = data.readInt32();
+            int rateLevel = data.readInt32();
+            status_t result = configureChannel(handle, rateLevel);
+            reply->writeInt32(result);
+            return NO_ERROR;
+        }
+
+    }
+    return BBinder::onTransact(code, data, reply, flags);
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/sensor/ISensorServer.cpp b/libs/sensor/ISensorServer.cpp
new file mode 100644
index 0000000..f41f187
--- /dev/null
+++ b/libs/sensor/ISensorServer.cpp
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sensor/ISensorServer.h>
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <cutils/native_handle.h>
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/Vector.h>
+#include <utils/Timers.h>
+
+#include <binder/Parcel.h>
+#include <binder/IInterface.h>
+
+#include <sensor/Sensor.h>
+#include <sensor/ISensorEventConnection.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+enum {
+    GET_SENSOR_LIST = IBinder::FIRST_CALL_TRANSACTION,
+    CREATE_SENSOR_EVENT_CONNECTION,
+    ENABLE_DATA_INJECTION,
+    GET_DYNAMIC_SENSOR_LIST,
+    CREATE_SENSOR_DIRECT_CONNECTION,
+};
+
+class BpSensorServer : public BpInterface<ISensorServer>
+{
+public:
+    explicit BpSensorServer(const sp<IBinder>& impl)
+        : BpInterface<ISensorServer>(impl)
+    {
+    }
+
+    virtual ~BpSensorServer();
+
+    virtual Vector<Sensor> getSensorList(const String16& opPackageName)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
+        data.writeString16(opPackageName);
+        remote()->transact(GET_SENSOR_LIST, data, &reply);
+        Sensor s;
+        Vector<Sensor> v;
+        uint32_t n = reply.readUint32();
+        v.setCapacity(n);
+        while (n--) {
+            reply.read(s);
+            v.add(s);
+        }
+        return v;
+    }
+
+    virtual Vector<Sensor> getDynamicSensorList(const String16& opPackageName)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
+        data.writeString16(opPackageName);
+        remote()->transact(GET_DYNAMIC_SENSOR_LIST, data, &reply);
+        Sensor s;
+        Vector<Sensor> v;
+        uint32_t n = reply.readUint32();
+        v.setCapacity(n);
+        while (n--) {
+            reply.read(s);
+            v.add(s);
+        }
+        return v;
+    }
+
+    virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName,
+             int mode, const String16& opPackageName)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
+        data.writeString8(packageName);
+        data.writeInt32(mode);
+        data.writeString16(opPackageName);
+        remote()->transact(CREATE_SENSOR_EVENT_CONNECTION, data, &reply);
+        return interface_cast<ISensorEventConnection>(reply.readStrongBinder());
+    }
+
+    virtual int isDataInjectionEnabled() {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
+        remote()->transact(ENABLE_DATA_INJECTION, data, &reply);
+        return reply.readInt32();
+    }
+
+    virtual sp<ISensorEventConnection> createSensorDirectConnection(const String16& opPackageName,
+            uint32_t size, int32_t type, int32_t format, const native_handle_t *resource) {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
+        data.writeString16(opPackageName);
+        data.writeUint32(size);
+        data.writeInt32(type);
+        data.writeInt32(format);
+        data.writeNativeHandle(resource);
+        remote()->transact(CREATE_SENSOR_DIRECT_CONNECTION, data, &reply);
+        return interface_cast<ISensorEventConnection>(reply.readStrongBinder());
+    }
+};
+
+// Out-of-line virtual method definition to trigger vtable emission in this
+// translation unit (see clang warning -Wweak-vtables)
+BpSensorServer::~BpSensorServer() {}
+
+IMPLEMENT_META_INTERFACE(SensorServer, "android.gui.SensorServer");
+
+// ----------------------------------------------------------------------
+
+status_t BnSensorServer::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code) {
+        case GET_SENSOR_LIST: {
+            CHECK_INTERFACE(ISensorServer, data, reply);
+            const String16& opPackageName = data.readString16();
+            Vector<Sensor> v(getSensorList(opPackageName));
+            size_t n = v.size();
+            reply->writeUint32(static_cast<uint32_t>(n));
+            for (size_t i = 0; i < n; i++) {
+                reply->write(v[i]);
+            }
+            return NO_ERROR;
+        }
+        case CREATE_SENSOR_EVENT_CONNECTION: {
+            CHECK_INTERFACE(ISensorServer, data, reply);
+            String8 packageName = data.readString8();
+            int32_t mode = data.readInt32();
+            const String16& opPackageName = data.readString16();
+            sp<ISensorEventConnection> connection(createSensorEventConnection(packageName, mode,
+                    opPackageName));
+            reply->writeStrongBinder(IInterface::asBinder(connection));
+            return NO_ERROR;
+        }
+        case ENABLE_DATA_INJECTION: {
+            CHECK_INTERFACE(ISensorServer, data, reply);
+            int32_t ret = isDataInjectionEnabled();
+            reply->writeInt32(static_cast<int32_t>(ret));
+            return NO_ERROR;
+        }
+        case GET_DYNAMIC_SENSOR_LIST: {
+            CHECK_INTERFACE(ISensorServer, data, reply);
+            const String16& opPackageName = data.readString16();
+            Vector<Sensor> v(getDynamicSensorList(opPackageName));
+            size_t n = v.size();
+            reply->writeUint32(static_cast<uint32_t>(n));
+            for (size_t i = 0; i < n; i++) {
+                reply->write(v[i]);
+            }
+            return NO_ERROR;
+        }
+        case CREATE_SENSOR_DIRECT_CONNECTION: {
+            CHECK_INTERFACE(ISensorServer, data, reply);
+            const String16& opPackageName = data.readString16();
+            uint32_t size = data.readUint32();
+            int32_t type = data.readInt32();
+            int32_t format = data.readInt32();
+            native_handle_t *resource = data.readNativeHandle();
+            sp<ISensorEventConnection> ch =
+                    createSensorDirectConnection(opPackageName, size, type, format, resource);
+            native_handle_close(resource);
+            native_handle_delete(resource);
+            reply->writeStrongBinder(IInterface::asBinder(ch));
+            return NO_ERROR;
+        }
+    }
+    return BBinder::onTransact(code, data, reply, flags);
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/sensor/Sensor.cpp b/libs/sensor/Sensor.cpp
new file mode 100644
index 0000000..c2d477e
--- /dev/null
+++ b/libs/sensor/Sensor.cpp
@@ -0,0 +1,578 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sensor/Sensor.h>
+
+#include <inttypes.h>
+
+#include <binder/AppOpsManager.h>
+#include <binder/IPermissionController.h>
+#include <binder/IServiceManager.h>
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+Sensor::Sensor(const char * name) :
+        mName(name), mHandle(0), mType(0),
+        mMinValue(0), mMaxValue(0), mResolution(0),
+        mPower(0), mMinDelay(0), mVersion(0), mFifoReservedEventCount(0),
+        mFifoMaxEventCount(0), mRequiredAppOp(0),
+        mMaxDelay(0), mFlags(0) {
+}
+
+Sensor::Sensor(struct sensor_t const* hwSensor, int halVersion) :
+        Sensor(*hwSensor, uuid_t(), halVersion) {
+}
+
+Sensor::Sensor(struct sensor_t const& hwSensor, const uuid_t& uuid, int halVersion) {
+    mName = hwSensor.name;
+    mVendor = hwSensor.vendor;
+    mVersion = hwSensor.version;
+    mHandle = hwSensor.handle;
+    mType = hwSensor.type;
+    mMinValue = 0;                      // FIXME: minValue
+    mMaxValue = hwSensor.maxRange;      // FIXME: maxValue
+    mResolution = hwSensor.resolution;
+    mPower = hwSensor.power;
+    mMinDelay = hwSensor.minDelay;
+    mFlags = 0;
+    mUuid = uuid;
+
+    // Set fifo event count zero for older devices which do not support batching. Fused
+    // sensors also have their fifo counts set to zero.
+    if (halVersion > SENSORS_DEVICE_API_VERSION_1_0) {
+        mFifoReservedEventCount = hwSensor.fifoReservedEventCount;
+        mFifoMaxEventCount = hwSensor.fifoMaxEventCount;
+    } else {
+        mFifoReservedEventCount = 0;
+        mFifoMaxEventCount = 0;
+    }
+
+    if (halVersion >= SENSORS_DEVICE_API_VERSION_1_3) {
+        if (hwSensor.maxDelay > INT_MAX) {
+            // Max delay is declared as a 64 bit integer for 64 bit architectures. But it should
+            // always fit in a 32 bit integer, log error and cap it to INT_MAX.
+            ALOGE("Sensor maxDelay overflow error %s %" PRId64, mName.string(),
+                  static_cast<int64_t>(hwSensor.maxDelay));
+            mMaxDelay = INT_MAX;
+        } else {
+            mMaxDelay = static_cast<int32_t>(hwSensor.maxDelay);
+        }
+    } else {
+        // For older hals set maxDelay to 0.
+        mMaxDelay = 0;
+    }
+
+    // Ensure existing sensors have correct string type, required permissions and reporting mode.
+    // Set reportingMode for all android defined sensor types, set wake-up flag only for proximity
+    // sensor, significant motion, tilt, pick_up gesture, wake gesture and glance gesture on older
+    // HALs. Newer HALs can define both wake-up and non wake-up proximity sensors.
+    // All the OEM defined defined sensors have flags set to whatever is provided by the HAL.
+    switch (mType) {
+    case SENSOR_TYPE_ACCELEROMETER:
+        mStringType = SENSOR_STRING_TYPE_ACCELEROMETER;
+        mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
+        break;
+    case SENSOR_TYPE_AMBIENT_TEMPERATURE:
+        mStringType = SENSOR_STRING_TYPE_AMBIENT_TEMPERATURE;
+        mFlags |= SENSOR_FLAG_ON_CHANGE_MODE;
+        break;
+    case SENSOR_TYPE_GAME_ROTATION_VECTOR:
+        mStringType = SENSOR_STRING_TYPE_GAME_ROTATION_VECTOR;
+        mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
+        break;
+    case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR:
+        mStringType = SENSOR_STRING_TYPE_GEOMAGNETIC_ROTATION_VECTOR;
+        mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
+        break;
+    case SENSOR_TYPE_GRAVITY:
+        mStringType = SENSOR_STRING_TYPE_GRAVITY;
+        mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
+        break;
+    case SENSOR_TYPE_GYROSCOPE:
+        mStringType = SENSOR_STRING_TYPE_GYROSCOPE;
+        mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
+        break;
+    case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
+        mStringType = SENSOR_STRING_TYPE_GYROSCOPE_UNCALIBRATED;
+        mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
+        break;
+    case SENSOR_TYPE_HEART_RATE: {
+        mStringType = SENSOR_STRING_TYPE_HEART_RATE;
+        mRequiredPermission = SENSOR_PERMISSION_BODY_SENSORS;
+        AppOpsManager appOps;
+        mRequiredAppOp = appOps.permissionToOpCode(String16(SENSOR_PERMISSION_BODY_SENSORS));
+        mFlags |= SENSOR_FLAG_ON_CHANGE_MODE;
+        } break;
+    case SENSOR_TYPE_LIGHT:
+        mStringType = SENSOR_STRING_TYPE_LIGHT;
+        mFlags |= SENSOR_FLAG_ON_CHANGE_MODE;
+        break;
+    case SENSOR_TYPE_LINEAR_ACCELERATION:
+        mStringType = SENSOR_STRING_TYPE_LINEAR_ACCELERATION;
+        mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
+        break;
+    case SENSOR_TYPE_MAGNETIC_FIELD:
+        mStringType = SENSOR_STRING_TYPE_MAGNETIC_FIELD;
+        mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
+        break;
+    case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
+        mStringType = SENSOR_STRING_TYPE_MAGNETIC_FIELD_UNCALIBRATED;
+        mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
+        break;
+    case SENSOR_TYPE_ORIENTATION:
+        mStringType = SENSOR_STRING_TYPE_ORIENTATION;
+        mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
+        break;
+    case SENSOR_TYPE_PRESSURE:
+        mStringType = SENSOR_STRING_TYPE_PRESSURE;
+        mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
+        break;
+    case SENSOR_TYPE_PROXIMITY:
+        mStringType = SENSOR_STRING_TYPE_PROXIMITY;
+        mFlags |= SENSOR_FLAG_ON_CHANGE_MODE;
+        if (halVersion < SENSORS_DEVICE_API_VERSION_1_3) {
+            mFlags |= SENSOR_FLAG_WAKE_UP;
+        }
+        break;
+    case SENSOR_TYPE_RELATIVE_HUMIDITY:
+        mStringType = SENSOR_STRING_TYPE_RELATIVE_HUMIDITY;
+        mFlags |= SENSOR_FLAG_ON_CHANGE_MODE;
+        break;
+    case SENSOR_TYPE_ROTATION_VECTOR:
+        mStringType = SENSOR_STRING_TYPE_ROTATION_VECTOR;
+        mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
+        break;
+    case SENSOR_TYPE_SIGNIFICANT_MOTION:
+        mStringType = SENSOR_STRING_TYPE_SIGNIFICANT_MOTION;
+        mFlags |= SENSOR_FLAG_ONE_SHOT_MODE;
+        if (halVersion < SENSORS_DEVICE_API_VERSION_1_3) {
+            mFlags |= SENSOR_FLAG_WAKE_UP;
+        }
+        break;
+    case SENSOR_TYPE_STEP_COUNTER:
+        mStringType = SENSOR_STRING_TYPE_STEP_COUNTER;
+        mFlags |= SENSOR_FLAG_ON_CHANGE_MODE;
+        break;
+    case SENSOR_TYPE_STEP_DETECTOR:
+        mStringType = SENSOR_STRING_TYPE_STEP_DETECTOR;
+        mFlags |= SENSOR_FLAG_SPECIAL_REPORTING_MODE;
+        break;
+    case SENSOR_TYPE_TEMPERATURE:
+        mStringType = SENSOR_STRING_TYPE_TEMPERATURE;
+        mFlags |= SENSOR_FLAG_ON_CHANGE_MODE;
+        break;
+    case SENSOR_TYPE_TILT_DETECTOR:
+        mStringType = SENSOR_STRING_TYPE_TILT_DETECTOR;
+        mFlags |= SENSOR_FLAG_SPECIAL_REPORTING_MODE;
+        if (halVersion < SENSORS_DEVICE_API_VERSION_1_3) {
+            mFlags |= SENSOR_FLAG_WAKE_UP;
+        }
+        break;
+    case SENSOR_TYPE_WAKE_GESTURE:
+        mStringType = SENSOR_STRING_TYPE_WAKE_GESTURE;
+        mFlags |= SENSOR_FLAG_ONE_SHOT_MODE;
+        if (halVersion < SENSORS_DEVICE_API_VERSION_1_3) {
+            mFlags |= SENSOR_FLAG_WAKE_UP;
+        }
+        break;
+    case SENSOR_TYPE_GLANCE_GESTURE:
+        mStringType = SENSOR_STRING_TYPE_GLANCE_GESTURE;
+        mFlags |= SENSOR_FLAG_ONE_SHOT_MODE;
+        if (halVersion < SENSORS_DEVICE_API_VERSION_1_3) {
+            mFlags |= SENSOR_FLAG_WAKE_UP;
+        }
+        break;
+    case SENSOR_TYPE_PICK_UP_GESTURE:
+        mStringType = SENSOR_STRING_TYPE_PICK_UP_GESTURE;
+        mFlags |= SENSOR_FLAG_ONE_SHOT_MODE;
+        if (halVersion < SENSORS_DEVICE_API_VERSION_1_3) {
+            mFlags |= SENSOR_FLAG_WAKE_UP;
+        }
+        break;
+    case SENSOR_TYPE_LOW_LATENCY_OFFBODY_DETECT:
+        mStringType = SENSOR_STRING_TYPE_LOW_LATENCY_OFFBODY_DETECT;
+        mFlags |= SENSOR_FLAG_ON_CHANGE_MODE;
+        break;
+    case SENSOR_TYPE_WRIST_TILT_GESTURE:
+        mStringType = SENSOR_STRING_TYPE_WRIST_TILT_GESTURE;
+        mFlags |= SENSOR_FLAG_SPECIAL_REPORTING_MODE;
+        if (halVersion < SENSORS_DEVICE_API_VERSION_1_3) {
+            mFlags |= SENSOR_FLAG_WAKE_UP;
+        }
+        break;
+    case SENSOR_TYPE_DYNAMIC_SENSOR_META:
+        mStringType = SENSOR_STRING_TYPE_DYNAMIC_SENSOR_META;
+        mFlags |= SENSOR_FLAG_SPECIAL_REPORTING_MODE; // special trigger
+        if (halVersion < SENSORS_DEVICE_API_VERSION_1_3) {
+            mFlags |= SENSOR_FLAG_WAKE_UP;
+        }
+        break;
+    case SENSOR_TYPE_POSE_6DOF:
+        mStringType = SENSOR_STRING_TYPE_POSE_6DOF;
+        mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
+        break;
+    case SENSOR_TYPE_STATIONARY_DETECT:
+        mStringType = SENSOR_STRING_TYPE_STATIONARY_DETECT;
+        mFlags |= SENSOR_FLAG_ONE_SHOT_MODE;
+        if (halVersion < SENSORS_DEVICE_API_VERSION_1_3) {
+            mFlags |= SENSOR_FLAG_WAKE_UP;
+        }
+        break;
+    case SENSOR_TYPE_MOTION_DETECT:
+        mStringType = SENSOR_STRING_TYPE_MOTION_DETECT;
+        mFlags |= SENSOR_FLAG_ONE_SHOT_MODE;
+        if (halVersion < SENSORS_DEVICE_API_VERSION_1_3) {
+            mFlags |= SENSOR_FLAG_WAKE_UP;
+        }
+        break;
+    case SENSOR_TYPE_HEART_BEAT:
+        mStringType = SENSOR_STRING_TYPE_HEART_BEAT;
+        mFlags |= SENSOR_FLAG_SPECIAL_REPORTING_MODE;
+        break;
+
+    // TODO:  Placeholder for LLOB sensor type
+
+
+    case SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED:
+        mStringType = SENSOR_STRING_TYPE_ACCELEROMETER_UNCALIBRATED;
+        mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
+        break;
+    default:
+        // Only pipe the stringType, requiredPermission and flags for custom sensors.
+        if (halVersion > SENSORS_DEVICE_API_VERSION_1_0 && hwSensor.stringType) {
+            mStringType = hwSensor.stringType;
+        }
+        if (halVersion > SENSORS_DEVICE_API_VERSION_1_0 && hwSensor.requiredPermission) {
+            mRequiredPermission = hwSensor.requiredPermission;
+            if (!strcmp(mRequiredPermission, SENSOR_PERMISSION_BODY_SENSORS)) {
+                AppOpsManager appOps;
+                mRequiredAppOp = appOps.permissionToOpCode(String16(SENSOR_PERMISSION_BODY_SENSORS));
+            }
+        }
+
+        if (halVersion >= SENSORS_DEVICE_API_VERSION_1_3) {
+            mFlags = static_cast<uint32_t>(hwSensor.flags);
+        } else {
+            // This is an OEM defined sensor on an older HAL. Use minDelay to determine the
+            // reporting mode of the sensor.
+            if (mMinDelay > 0) {
+                mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
+            } else if (mMinDelay == 0) {
+                mFlags |= SENSOR_FLAG_ON_CHANGE_MODE;
+            } else if (mMinDelay < 0) {
+                mFlags |= SENSOR_FLAG_ONE_SHOT_MODE;
+            }
+        }
+        break;
+    }
+
+    if (halVersion >= SENSORS_DEVICE_API_VERSION_1_3) {
+        // Wake-up flag of HAL 1.3 and above is set here
+        mFlags |= (hwSensor.flags & SENSOR_FLAG_WAKE_UP);
+
+        // Log error if the reporting mode is not as expected, but respect HAL setting.
+        int actualReportingMode = (hwSensor.flags & REPORTING_MODE_MASK) >> REPORTING_MODE_SHIFT;
+        int expectedReportingMode = (mFlags & REPORTING_MODE_MASK) >> REPORTING_MODE_SHIFT;
+        if (actualReportingMode != expectedReportingMode) {
+            ALOGE("Reporting Mode incorrect: sensor %s handle=%#010" PRIx32 " type=%" PRId32 " "
+                   "actual=%d expected=%d",
+                   mName.string(), mHandle, mType, actualReportingMode, expectedReportingMode);
+        }
+    }
+
+    // Feature flags
+    // Set DYNAMIC_SENSOR_MASK and ADDITIONAL_INFO_MASK flag here. Compatible with HAL 1_3.
+    if (halVersion >= SENSORS_DEVICE_API_VERSION_1_3) {
+        mFlags |= hwSensor.flags & (DYNAMIC_SENSOR_MASK | ADDITIONAL_INFO_MASK);
+    }
+    // Set DIRECT_REPORT_MASK and DIRECT_CHANNEL_MASK flags. Compatible with HAL 1_3.
+    if (halVersion >= SENSORS_DEVICE_API_VERSION_1_3) {
+        // only on continuous sensors direct report mode is defined
+        if ((mFlags & REPORTING_MODE_MASK) == SENSOR_FLAG_CONTINUOUS_MODE) {
+            mFlags |= hwSensor.flags
+                & (SENSOR_FLAG_MASK_DIRECT_REPORT | SENSOR_FLAG_MASK_DIRECT_CHANNEL);
+        }
+    }
+    // Set DATA_INJECTION flag here. Defined in HAL 1_4.
+    if (halVersion >= SENSORS_DEVICE_API_VERSION_1_4) {
+        mFlags |= (hwSensor.flags & DATA_INJECTION_MASK);
+    }
+
+    if (mRequiredPermission.length() > 0) {
+        // If the sensor is protected by a permission we need to know if it is
+        // a runtime one to determine whether we can use the permission cache.
+        sp<IBinder> binder = defaultServiceManager()->getService(String16("permission"));
+        if (binder != 0) {
+            sp<IPermissionController> permCtrl = interface_cast<IPermissionController>(binder);
+            mRequiredPermissionRuntime = permCtrl->isRuntimePermission(
+                    String16(mRequiredPermission));
+        }
+    }
+}
+
+Sensor::~Sensor() {
+}
+
+const String8& Sensor::getName() const {
+    return mName;
+}
+
+const String8& Sensor::getVendor() const {
+    return mVendor;
+}
+
+int32_t Sensor::getHandle() const {
+    return mHandle;
+}
+
+int32_t Sensor::getType() const {
+    return mType;
+}
+
+float Sensor::getMinValue() const {
+    return mMinValue;
+}
+
+float Sensor::getMaxValue() const {
+    return mMaxValue;
+}
+
+float Sensor::getResolution() const {
+    return mResolution;
+}
+
+float Sensor::getPowerUsage() const {
+    return mPower;
+}
+
+int32_t Sensor::getMinDelay() const {
+    return mMinDelay;
+}
+
+nsecs_t Sensor::getMinDelayNs() const {
+    return getMinDelay() * 1000;
+}
+
+int32_t Sensor::getVersion() const {
+    return mVersion;
+}
+
+uint32_t Sensor::getFifoReservedEventCount() const {
+    return mFifoReservedEventCount;
+}
+
+uint32_t Sensor::getFifoMaxEventCount() const {
+    return mFifoMaxEventCount;
+}
+
+const String8& Sensor::getStringType() const {
+    return mStringType;
+}
+
+const String8& Sensor::getRequiredPermission() const {
+    return mRequiredPermission;
+}
+
+bool Sensor::isRequiredPermissionRuntime() const {
+    return mRequiredPermissionRuntime;
+}
+
+int32_t Sensor::getRequiredAppOp() const {
+    return mRequiredAppOp;
+}
+
+int32_t Sensor::getMaxDelay() const {
+    return mMaxDelay;
+}
+
+uint32_t Sensor::getFlags() const {
+    return mFlags;
+}
+
+bool Sensor::isWakeUpSensor() const {
+    return (mFlags & SENSOR_FLAG_WAKE_UP) != 0;
+}
+
+bool Sensor::isDynamicSensor() const {
+    return (mFlags & SENSOR_FLAG_DYNAMIC_SENSOR) != 0;
+}
+
+bool Sensor::hasAdditionalInfo() const {
+    return (mFlags & SENSOR_FLAG_ADDITIONAL_INFO) != 0;
+}
+
+int32_t Sensor::getHighestDirectReportRateLevel() const {
+    return ((mFlags & SENSOR_FLAG_MASK_DIRECT_REPORT) >> SENSOR_FLAG_SHIFT_DIRECT_REPORT);
+}
+
+bool Sensor::isDirectChannelTypeSupported(int32_t sharedMemType) const {
+    switch (sharedMemType) {
+        case SENSOR_DIRECT_MEM_TYPE_ASHMEM:
+            return mFlags & SENSOR_FLAG_DIRECT_CHANNEL_ASHMEM;
+        case SENSOR_DIRECT_MEM_TYPE_GRALLOC:
+            return mFlags & SENSOR_FLAG_DIRECT_CHANNEL_GRALLOC;
+        default:
+            return false;
+    }
+}
+
+int32_t Sensor::getReportingMode() const {
+    return ((mFlags & REPORTING_MODE_MASK) >> REPORTING_MODE_SHIFT);
+}
+
+const Sensor::uuid_t& Sensor::getUuid() const {
+    return mUuid;
+}
+
+void Sensor::setId(int32_t id) {
+    mUuid.i64[0] = id;
+    mUuid.i64[1] = 0;
+}
+
+int32_t Sensor::getId() const {
+    return int32_t(mUuid.i64[0]);
+}
+
+size_t Sensor::getFlattenedSize() const {
+    size_t fixedSize =
+            sizeof(mVersion) + sizeof(mHandle) + sizeof(mType) +
+            sizeof(mMinValue) + sizeof(mMaxValue) + sizeof(mResolution) +
+            sizeof(mPower) + sizeof(mMinDelay) + sizeof(mFifoMaxEventCount) +
+            sizeof(mFifoMaxEventCount) + sizeof(mRequiredPermissionRuntime) +
+            sizeof(mRequiredAppOp) + sizeof(mMaxDelay) + sizeof(mFlags) + sizeof(mUuid);
+
+    size_t variableSize =
+            sizeof(uint32_t) + FlattenableUtils::align<4>(mName.length()) +
+            sizeof(uint32_t) + FlattenableUtils::align<4>(mVendor.length()) +
+            sizeof(uint32_t) + FlattenableUtils::align<4>(mStringType.length()) +
+            sizeof(uint32_t) + FlattenableUtils::align<4>(mRequiredPermission.length());
+
+    return fixedSize + variableSize;
+}
+
+status_t Sensor::flatten(void* buffer, size_t size) const {
+    if (size < getFlattenedSize()) {
+        return NO_MEMORY;
+    }
+
+    flattenString8(buffer, size, mName);
+    flattenString8(buffer, size, mVendor);
+    FlattenableUtils::write(buffer, size, mVersion);
+    FlattenableUtils::write(buffer, size, mHandle);
+    FlattenableUtils::write(buffer, size, mType);
+    FlattenableUtils::write(buffer, size, mMinValue);
+    FlattenableUtils::write(buffer, size, mMaxValue);
+    FlattenableUtils::write(buffer, size, mResolution);
+    FlattenableUtils::write(buffer, size, mPower);
+    FlattenableUtils::write(buffer, size, mMinDelay);
+    FlattenableUtils::write(buffer, size, mFifoReservedEventCount);
+    FlattenableUtils::write(buffer, size, mFifoMaxEventCount);
+    flattenString8(buffer, size, mStringType);
+    flattenString8(buffer, size, mRequiredPermission);
+    FlattenableUtils::write(buffer, size, mRequiredPermissionRuntime);
+    FlattenableUtils::write(buffer, size, mRequiredAppOp);
+    FlattenableUtils::write(buffer, size, mMaxDelay);
+    FlattenableUtils::write(buffer, size, mFlags);
+    if (mUuid.i64[1] != 0) {
+        // We should never hit this case with our current API, but we
+        // could via a careless API change.  If that happens,
+        // this code will keep us from leaking our UUID (while probably
+        // breaking dynamic sensors).  See b/29547335.
+        ALOGW("Sensor with UUID being flattened; sending 0.  Expect "
+              "bad dynamic sensor behavior");
+        uuid_t tmpUuid;  // default constructor makes this 0.
+        FlattenableUtils::write(buffer, size, tmpUuid);
+    } else {
+        FlattenableUtils::write(buffer, size, mUuid);
+    }
+    return NO_ERROR;
+}
+
+status_t Sensor::unflatten(void const* buffer, size_t size) {
+    if (!unflattenString8(buffer, size, mName)) {
+        return NO_MEMORY;
+    }
+    if (!unflattenString8(buffer, size, mVendor)) {
+        return NO_MEMORY;
+    }
+
+    size_t fixedSize1 =
+            sizeof(mVersion) + sizeof(mHandle) + sizeof(mType) + sizeof(mMinValue) +
+            sizeof(mMaxValue) + sizeof(mResolution) + sizeof(mPower) + sizeof(mMinDelay) +
+            sizeof(mFifoMaxEventCount) + sizeof(mFifoMaxEventCount);
+    if (size < fixedSize1) {
+        return NO_MEMORY;
+    }
+
+    FlattenableUtils::read(buffer, size, mVersion);
+    FlattenableUtils::read(buffer, size, mHandle);
+    FlattenableUtils::read(buffer, size, mType);
+    FlattenableUtils::read(buffer, size, mMinValue);
+    FlattenableUtils::read(buffer, size, mMaxValue);
+    FlattenableUtils::read(buffer, size, mResolution);
+    FlattenableUtils::read(buffer, size, mPower);
+    FlattenableUtils::read(buffer, size, mMinDelay);
+    FlattenableUtils::read(buffer, size, mFifoReservedEventCount);
+    FlattenableUtils::read(buffer, size, mFifoMaxEventCount);
+
+    if (!unflattenString8(buffer, size, mStringType)) {
+        return NO_MEMORY;
+    }
+    if (!unflattenString8(buffer, size, mRequiredPermission)) {
+        return NO_MEMORY;
+    }
+
+    size_t fixedSize2 =
+            sizeof(mRequiredPermissionRuntime) + sizeof(mRequiredAppOp) + sizeof(mMaxDelay) +
+            sizeof(mFlags) + sizeof(mUuid);
+    if (size < fixedSize2) {
+        return NO_MEMORY;
+    }
+
+    FlattenableUtils::read(buffer, size, mRequiredPermissionRuntime);
+    FlattenableUtils::read(buffer, size, mRequiredAppOp);
+    FlattenableUtils::read(buffer, size, mMaxDelay);
+    FlattenableUtils::read(buffer, size, mFlags);
+    FlattenableUtils::read(buffer, size, mUuid);
+    return NO_ERROR;
+}
+
+void Sensor::flattenString8(void*& buffer, size_t& size,
+        const String8& string8) {
+    uint32_t len = static_cast<uint32_t>(string8.length());
+    FlattenableUtils::write(buffer, size, len);
+    memcpy(static_cast<char*>(buffer), string8.string(), len);
+    FlattenableUtils::advance(buffer, size, FlattenableUtils::align<4>(len));
+}
+
+bool Sensor::unflattenString8(void const*& buffer, size_t& size, String8& outputString8) {
+    uint32_t len;
+    if (size < sizeof(len)) {
+        return false;
+    }
+    FlattenableUtils::read(buffer, size, len);
+    if (size < len) {
+        return false;
+    }
+    outputString8.setTo(static_cast<char const*>(buffer), len);
+    FlattenableUtils::advance(buffer, size, FlattenableUtils::align<4>(len));
+    return true;
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/sensor/SensorEventQueue.cpp b/libs/sensor/SensorEventQueue.cpp
new file mode 100644
index 0000000..8ba3ebe
--- /dev/null
+++ b/libs/sensor/SensorEventQueue.cpp
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "Sensors"
+
+#include <sensor/SensorEventQueue.h>
+
+#include <algorithm>
+#include <sys/socket.h>
+
+#include <utils/RefBase.h>
+#include <utils/Looper.h>
+
+#include <sensor/Sensor.h>
+#include <sensor/BitTube.h>
+#include <sensor/ISensorEventConnection.h>
+
+#include <android/sensor.h>
+
+using std::min;
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+SensorEventQueue::SensorEventQueue(const sp<ISensorEventConnection>& connection)
+    : mSensorEventConnection(connection), mRecBuffer(NULL), mAvailable(0), mConsumed(0),
+      mNumAcksToSend(0) {
+    mRecBuffer = new ASensorEvent[MAX_RECEIVE_BUFFER_EVENT_COUNT];
+}
+
+SensorEventQueue::~SensorEventQueue() {
+    delete [] mRecBuffer;
+}
+
+void SensorEventQueue::onFirstRef()
+{
+    mSensorChannel = mSensorEventConnection->getSensorChannel();
+}
+
+int SensorEventQueue::getFd() const
+{
+    return mSensorChannel->getFd();
+}
+
+
+ssize_t SensorEventQueue::write(const sp<BitTube>& tube,
+        ASensorEvent const* events, size_t numEvents) {
+    return BitTube::sendObjects(tube, events, numEvents);
+}
+
+ssize_t SensorEventQueue::read(ASensorEvent* events, size_t numEvents) {
+    if (mAvailable == 0) {
+        ssize_t err = BitTube::recvObjects(mSensorChannel,
+                mRecBuffer, MAX_RECEIVE_BUFFER_EVENT_COUNT);
+        if (err < 0) {
+            return err;
+        }
+        mAvailable = static_cast<size_t>(err);
+        mConsumed = 0;
+    }
+    size_t count = min(numEvents, mAvailable);
+    memcpy(events, mRecBuffer + mConsumed, count * sizeof(ASensorEvent));
+    mAvailable -= count;
+    mConsumed += count;
+    return static_cast<ssize_t>(count);
+}
+
+sp<Looper> SensorEventQueue::getLooper() const
+{
+    Mutex::Autolock _l(mLock);
+    if (mLooper == 0) {
+        mLooper = new Looper(true);
+        mLooper->addFd(getFd(), getFd(), ALOOPER_EVENT_INPUT, NULL, NULL);
+    }
+    return mLooper;
+}
+
+status_t SensorEventQueue::waitForEvent() const
+{
+    const int fd = getFd();
+    sp<Looper> looper(getLooper());
+
+    int events;
+    int32_t result;
+    do {
+        result = looper->pollOnce(-1, NULL, &events, NULL);
+        if (result == ALOOPER_POLL_ERROR) {
+            ALOGE("SensorEventQueue::waitForEvent error (errno=%d)", errno);
+            result = -EPIPE; // unknown error, so we make up one
+            break;
+        }
+        if (events & ALOOPER_EVENT_HANGUP) {
+            // the other-side has died
+            ALOGE("SensorEventQueue::waitForEvent error HANGUP");
+            result = -EPIPE; // unknown error, so we make up one
+            break;
+        }
+    } while (result != fd);
+
+    return  (result == fd) ? status_t(NO_ERROR) : result;
+}
+
+status_t SensorEventQueue::wake() const
+{
+    sp<Looper> looper(getLooper());
+    looper->wake();
+    return NO_ERROR;
+}
+
+status_t SensorEventQueue::enableSensor(Sensor const* sensor) const {
+    return enableSensor(sensor, SENSOR_DELAY_NORMAL);
+}
+
+status_t SensorEventQueue::enableSensor(Sensor const* sensor, int32_t samplingPeriodUs) const {
+    return mSensorEventConnection->enableDisable(sensor->getHandle(), true,
+                                                 us2ns(samplingPeriodUs), 0, 0);
+}
+
+status_t SensorEventQueue::disableSensor(Sensor const* sensor) const {
+    return mSensorEventConnection->enableDisable(sensor->getHandle(), false, 0, 0, 0);
+}
+
+status_t SensorEventQueue::enableSensor(int32_t handle, int32_t samplingPeriodUs,
+                                        int maxBatchReportLatencyUs, int reservedFlags) const {
+    return mSensorEventConnection->enableDisable(handle, true, us2ns(samplingPeriodUs),
+                                                 us2ns(maxBatchReportLatencyUs), reservedFlags);
+}
+
+status_t SensorEventQueue::flush() const {
+    return mSensorEventConnection->flush();
+}
+
+status_t SensorEventQueue::disableSensor(int32_t handle) const {
+    return mSensorEventConnection->enableDisable(handle, false, 0, 0, false);
+}
+
+status_t SensorEventQueue::setEventRate(Sensor const* sensor, nsecs_t ns) const {
+    return mSensorEventConnection->setEventRate(sensor->getHandle(), ns);
+}
+
+status_t SensorEventQueue::injectSensorEvent(const ASensorEvent& event) {
+    do {
+        // Blocking call.
+        ssize_t size = ::send(mSensorChannel->getFd(), &event, sizeof(event), MSG_NOSIGNAL);
+        if (size >= 0) {
+            return NO_ERROR;
+        } else if (size < 0 && errno == EAGAIN) {
+            // If send is returning a "Try again" error, sleep for 100ms and try again. In all
+            // other cases log a failure and exit.
+            usleep(100000);
+        } else {
+            ALOGE("injectSensorEvent failure %s %zd", strerror(errno), size);
+            return INVALID_OPERATION;
+        }
+    } while (true);
+}
+
+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) {
+            ++mNumAcksToSend;
+        }
+    }
+    // Send mNumAcksToSend to acknowledge for the wake up sensor events received.
+    if (mNumAcksToSend > 0) {
+        ssize_t size = ::send(mSensorChannel->getFd(), &mNumAcksToSend, sizeof(mNumAcksToSend),
+                MSG_DONTWAIT | MSG_NOSIGNAL);
+        if (size < 0) {
+            ALOGE("sendAck failure %zd %d", size, mNumAcksToSend);
+        } else {
+            mNumAcksToSend = 0;
+        }
+    }
+    return;
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
diff --git a/libs/sensor/SensorManager.cpp b/libs/sensor/SensorManager.cpp
new file mode 100644
index 0000000..b6e9fa1
--- /dev/null
+++ b/libs/sensor/SensorManager.cpp
@@ -0,0 +1,301 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "Sensors"
+
+#include <sensor/SensorManager.h>
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <cutils/native_handle.h>
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/Singleton.h>
+
+#include <binder/IBinder.h>
+#include <binder/IServiceManager.h>
+
+#include <sensor/ISensorServer.h>
+#include <sensor/ISensorEventConnection.h>
+#include <sensor/Sensor.h>
+#include <sensor/SensorEventQueue.h>
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+android::Mutex android::SensorManager::sLock;
+std::map<String16, SensorManager*> android::SensorManager::sPackageInstances;
+
+SensorManager& SensorManager::getInstanceForPackage(const String16& packageName) {
+    Mutex::Autolock _l(sLock);
+    SensorManager* sensorManager;
+    std::map<String16, SensorManager*>::iterator iterator =
+        sPackageInstances.find(packageName);
+
+    if (iterator != sPackageInstances.end()) {
+        sensorManager = iterator->second;
+    } else {
+        String16 opPackageName = packageName;
+
+        // It is possible that the calling code has no access to the package name.
+        // In this case we will get the packages for the calling UID and pick the
+        // first one for attributing the app op. This will work correctly for
+        // runtime permissions as for legacy apps we will toggle the app op for
+        // all packages in the UID. The caveat is that the operation may be attributed
+        // to the wrong package and stats based on app ops may be slightly off.
+        if (opPackageName.size() <= 0) {
+            sp<IBinder> binder = defaultServiceManager()->getService(String16("permission"));
+            if (binder != 0) {
+                const uid_t uid = IPCThreadState::self()->getCallingUid();
+                Vector<String16> packages;
+                interface_cast<IPermissionController>(binder)->getPackagesForUid(uid, packages);
+                if (!packages.isEmpty()) {
+                    opPackageName = packages[0];
+                } else {
+                    ALOGE("No packages for calling UID");
+                }
+            } else {
+                ALOGE("Cannot get permission service");
+            }
+        }
+
+        sensorManager = new SensorManager(opPackageName);
+
+        // If we had no package name, we looked it up from the UID and the sensor
+        // manager instance we created should also be mapped to the empty package
+        // name, to avoid looking up the packages for a UID and get the same result.
+        if (packageName.size() <= 0) {
+            sPackageInstances.insert(std::make_pair(String16(), sensorManager));
+        }
+
+        // Stash the per package sensor manager.
+        sPackageInstances.insert(std::make_pair(opPackageName, sensorManager));
+    }
+
+    return *sensorManager;
+}
+
+SensorManager::SensorManager(const String16& opPackageName)
+    : mSensorList(0), mOpPackageName(opPackageName), mDirectConnectionHandle(1) {
+    // okay we're not locked here, but it's not needed during construction
+    assertStateLocked();
+}
+
+SensorManager::~SensorManager() {
+    free(mSensorList);
+}
+
+void SensorManager::sensorManagerDied() {
+    Mutex::Autolock _l(mLock);
+    mSensorServer.clear();
+    free(mSensorList);
+    mSensorList = NULL;
+    mSensors.clear();
+}
+
+status_t SensorManager::assertStateLocked() {
+    bool initSensorManager = false;
+    if (mSensorServer == NULL) {
+        initSensorManager = true;
+    } else {
+        // Ping binder to check if sensorservice is alive.
+        status_t err = IInterface::asBinder(mSensorServer)->pingBinder();
+        if (err != NO_ERROR) {
+            initSensorManager = true;
+        }
+    }
+    if (initSensorManager) {
+        // try for 300 seconds (60*5(getService() tries for 5 seconds)) before giving up ...
+        const String16 name("sensorservice");
+        for (int i = 0; i < 60; i++) {
+            status_t err = getService(name, &mSensorServer);
+            if (err == NAME_NOT_FOUND) {
+                sleep(1);
+                continue;
+            }
+            if (err != NO_ERROR) {
+                return err;
+            }
+            break;
+        }
+
+        class DeathObserver : public IBinder::DeathRecipient {
+            SensorManager& mSensorManager;
+            virtual void binderDied(const wp<IBinder>& who) {
+                ALOGW("sensorservice died [%p]", who.unsafe_get());
+                mSensorManager.sensorManagerDied();
+            }
+        public:
+            explicit DeathObserver(SensorManager& mgr) : mSensorManager(mgr) { }
+        };
+
+        LOG_ALWAYS_FATAL_IF(mSensorServer.get() == NULL, "getService(SensorService) NULL");
+
+        mDeathObserver = new DeathObserver(*const_cast<SensorManager *>(this));
+        IInterface::asBinder(mSensorServer)->linkToDeath(mDeathObserver);
+
+        mSensors = mSensorServer->getSensorList(mOpPackageName);
+        size_t count = mSensors.size();
+        mSensorList =
+                static_cast<Sensor const**>(malloc(count * sizeof(Sensor*)));
+        LOG_ALWAYS_FATAL_IF(mSensorList == NULL, "mSensorList NULL");
+
+        for (size_t i=0 ; i<count ; i++) {
+            mSensorList[i] = mSensors.array() + i;
+        }
+    }
+
+    return NO_ERROR;
+}
+
+ssize_t SensorManager::getSensorList(Sensor const* const** list) {
+    Mutex::Autolock _l(mLock);
+    status_t err = assertStateLocked();
+    if (err < 0) {
+        return static_cast<ssize_t>(err);
+    }
+    *list = mSensorList;
+    return static_cast<ssize_t>(mSensors.size());
+}
+
+ssize_t SensorManager::getDynamicSensorList(Vector<Sensor> & dynamicSensors) {
+    Mutex::Autolock _l(mLock);
+    status_t err = assertStateLocked();
+    if (err < 0) {
+        return static_cast<ssize_t>(err);
+    }
+
+    dynamicSensors = mSensorServer->getDynamicSensorList(mOpPackageName);
+    size_t count = dynamicSensors.size();
+
+    return static_cast<ssize_t>(count);
+}
+
+Sensor const* SensorManager::getDefaultSensor(int type)
+{
+    Mutex::Autolock _l(mLock);
+    if (assertStateLocked() == NO_ERROR) {
+        bool wakeUpSensor = false;
+        // For the following sensor types, return a wake-up sensor. These types are by default
+        // defined as wake-up sensors. For the rest of the sensor types defined in sensors.h return
+        // a non_wake-up version.
+        if (type == SENSOR_TYPE_PROXIMITY || type == SENSOR_TYPE_SIGNIFICANT_MOTION ||
+            type == SENSOR_TYPE_TILT_DETECTOR || type == SENSOR_TYPE_WAKE_GESTURE ||
+            type == SENSOR_TYPE_GLANCE_GESTURE || type == SENSOR_TYPE_PICK_UP_GESTURE ||
+            type == SENSOR_TYPE_WRIST_TILT_GESTURE ||
+            type == SENSOR_TYPE_LOW_LATENCY_OFFBODY_DETECT) {
+            wakeUpSensor = true;
+        }
+        // For now we just return the first sensor of that type we find.
+        // in the future it will make sense to let the SensorService make
+        // that decision.
+        for (size_t i=0 ; i<mSensors.size() ; i++) {
+            if (mSensorList[i]->getType() == type &&
+                mSensorList[i]->isWakeUpSensor() == wakeUpSensor) {
+                return mSensorList[i];
+            }
+        }
+    }
+    return NULL;
+}
+
+sp<SensorEventQueue> SensorManager::createEventQueue(String8 packageName, int mode) {
+    sp<SensorEventQueue> queue;
+
+    Mutex::Autolock _l(mLock);
+    while (assertStateLocked() == NO_ERROR) {
+        sp<ISensorEventConnection> connection =
+                mSensorServer->createSensorEventConnection(packageName, mode, mOpPackageName);
+        if (connection == NULL) {
+            // SensorService just died or the app doesn't have required permissions.
+            ALOGE("createEventQueue: connection is NULL.");
+            return NULL;
+        }
+        queue = new SensorEventQueue(connection);
+        break;
+    }
+    return queue;
+}
+
+bool SensorManager::isDataInjectionEnabled() {
+    Mutex::Autolock _l(mLock);
+    if (assertStateLocked() == NO_ERROR) {
+        return mSensorServer->isDataInjectionEnabled();
+    }
+    return false;
+}
+
+int SensorManager::createDirectChannel(
+        size_t size, int channelType, const native_handle_t *resourceHandle) {
+    Mutex::Autolock _l(mLock);
+    if (assertStateLocked() != NO_ERROR) {
+        return NO_INIT;
+    }
+
+    switch (channelType) {
+        case SENSOR_DIRECT_MEM_TYPE_ASHMEM: {
+            sp<ISensorEventConnection> conn =
+                      mSensorServer->createSensorDirectConnection(mOpPackageName,
+                          static_cast<uint32_t>(size),
+                          static_cast<int32_t>(channelType),
+                          SENSOR_DIRECT_FMT_SENSORS_EVENT, resourceHandle);
+            if (conn == nullptr) {
+                return NO_MEMORY;
+            }
+            int nativeHandle = mDirectConnectionHandle++;
+            mDirectConnection.emplace(nativeHandle, conn);
+            return nativeHandle;
+        }
+        case SENSOR_DIRECT_MEM_TYPE_GRALLOC:
+            LOG_FATAL("%s: Finish implementation of ION and GRALLOC or remove", __FUNCTION__);
+            return BAD_VALUE;
+        default:
+            ALOGE("Bad channel shared memory type %d", channelType);
+            return BAD_VALUE;
+    }
+}
+
+void SensorManager::destroyDirectChannel(int channelNativeHandle) {
+    Mutex::Autolock _l(mLock);
+    if (assertStateLocked() == NO_ERROR) {
+        mDirectConnection.erase(channelNativeHandle);
+    }
+}
+
+int SensorManager::configureDirectChannel(int channelNativeHandle, int sensorHandle, int rateLevel) {
+    Mutex::Autolock _l(mLock);
+    if (assertStateLocked() != NO_ERROR) {
+        return NO_INIT;
+    }
+
+    auto i = mDirectConnection.find(channelNativeHandle);
+    if (i == mDirectConnection.end()) {
+        ALOGE("Cannot find the handle in client direct connection table");
+        return BAD_VALUE;
+    }
+
+    int ret;
+    ret = i->second->configureChannel(sensorHandle, rateLevel);
+    ALOGE_IF(ret < 0, "SensorManager::configureChannel (%d, %d) returns %d",
+            static_cast<int>(sensorHandle), static_cast<int>(rateLevel),
+            static_cast<int>(ret));
+    return ret;
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/sensor/include/sensor/BitTube.h b/libs/sensor/include/sensor/BitTube.h
new file mode 100644
index 0000000..c1fabe8
--- /dev/null
+++ b/libs/sensor/include/sensor/BitTube.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+class Parcel;
+
+class BitTube : public RefBase
+{
+public:
+
+    // creates a BitTube with a default (4KB) send buffer
+    BitTube();
+
+    // creates a BitTube with a a specified send and receive buffer size
+    explicit BitTube(size_t bufsize);
+
+    explicit BitTube(const Parcel& data);
+    virtual ~BitTube();
+
+    // check state after construction
+    status_t initCheck() const;
+
+    // get receive file-descriptor
+    int getFd() const;
+
+    // get the send file-descriptor.
+    int getSendFd() const;
+
+    // send objects (sized blobs). All objects are guaranteed to be written or the call fails.
+    template <typename T>
+    static ssize_t sendObjects(const sp<BitTube>& tube,
+            T const* events, size_t count) {
+        return sendObjects(tube, events, count, sizeof(T));
+    }
+
+    // receive objects (sized blobs). If the receiving buffer isn't large enough,
+    // excess messages are silently discarded.
+    template <typename T>
+    static ssize_t recvObjects(const sp<BitTube>& tube,
+            T* events, size_t count) {
+        return recvObjects(tube, events, count, sizeof(T));
+    }
+
+    // parcels this BitTube
+    status_t writeToParcel(Parcel* reply) const;
+
+private:
+    void init(size_t rcvbuf, size_t sndbuf);
+
+    // send a message. The write is guaranteed to send the whole message or fail.
+    ssize_t write(void const* vaddr, size_t size);
+
+    // receive a message. the passed buffer must be at least as large as the
+    // write call used to send the message, excess data is silently discarded.
+    ssize_t read(void* vaddr, size_t size);
+
+    int mSendFd;
+    mutable int mReceiveFd;
+
+    static ssize_t sendObjects(const sp<BitTube>& tube,
+            void const* events, size_t count, size_t objSize);
+
+    static ssize_t recvObjects(const sp<BitTube>& tube,
+            void* events, size_t count, size_t objSize);
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/sensor/include/sensor/ISensorEventConnection.h b/libs/sensor/include/sensor/ISensorEventConnection.h
new file mode 100644
index 0000000..07cc7e8
--- /dev/null
+++ b/libs/sensor/include/sensor/ISensorEventConnection.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/StrongPointer.h>
+#include <utils/Timers.h>
+
+#include <binder/IInterface.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+class BitTube;
+class Parcel;
+
+class ISensorEventConnection : public IInterface
+{
+public:
+    DECLARE_META_INTERFACE(SensorEventConnection)
+
+    virtual sp<BitTube> getSensorChannel() const = 0;
+    virtual status_t enableDisable(int handle, bool enabled, nsecs_t samplingPeriodNs,
+                                   nsecs_t maxBatchReportLatencyNs, int reservedFlags) = 0;
+    virtual status_t setEventRate(int handle, nsecs_t ns) = 0;
+    virtual status_t flush() = 0;
+    virtual int32_t configureChannel(int32_t handle, int32_t rateLevel) = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnSensorEventConnection : public BnInterface<ISensorEventConnection>
+{
+public:
+    virtual status_t    onTransact( uint32_t code,
+                                    const Parcel& data,
+                                    Parcel* reply,
+                                    uint32_t flags = 0);
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/sensor/include/sensor/ISensorServer.h b/libs/sensor/include/sensor/ISensorServer.h
new file mode 100644
index 0000000..f922307
--- /dev/null
+++ b/libs/sensor/include/sensor/ISensorServer.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/StrongPointer.h>
+#include <utils/Vector.h>
+
+#include <binder/IInterface.h>
+
+struct native_handle;
+typedef struct native_handle native_handle_t;
+namespace android {
+// ----------------------------------------------------------------------------
+
+class ISensorEventConnection;
+class Parcel;
+class Sensor;
+class String8;
+class String16;
+
+class ISensorServer : public IInterface
+{
+public:
+    DECLARE_META_INTERFACE(SensorServer)
+
+    virtual Vector<Sensor> getSensorList(const String16& opPackageName) = 0;
+    virtual Vector<Sensor> getDynamicSensorList(const String16& opPackageName) = 0;
+
+    virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName,
+             int mode, const String16& opPackageName) = 0;
+    virtual int32_t isDataInjectionEnabled() = 0;
+
+    virtual sp<ISensorEventConnection> createSensorDirectConnection(const String16& opPackageName,
+            uint32_t size, int32_t type, int32_t format, const native_handle_t *resource) = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnSensorServer : public BnInterface<ISensorServer>
+{
+public:
+    virtual status_t    onTransact( uint32_t code,
+                                    const Parcel& data,
+                                    Parcel* reply,
+                                    uint32_t flags = 0);
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/sensor/include/sensor/Sensor.h b/libs/sensor/include/sensor/Sensor.h
new file mode 100644
index 0000000..043e635
--- /dev/null
+++ b/libs/sensor/include/sensor/Sensor.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/Flattenable.h>
+#include <utils/String8.h>
+#include <utils/Timers.h>
+
+// FIXME: including from android/ breaks layering, as libandroid ultimately depends on libsensors
+#include <android/sensor.h>
+
+#include <hardware/sensors.h>
+
+// ----------------------------------------------------------------------------
+// Concrete types for the NDK
+struct ASensor { };
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+class Parcel;
+
+// ----------------------------------------------------------------------------
+
+class Sensor : public ASensor, public LightFlattenable<Sensor>
+{
+public:
+    enum {
+        TYPE_ACCELEROMETER  = ASENSOR_TYPE_ACCELEROMETER,
+        TYPE_MAGNETIC_FIELD = ASENSOR_TYPE_MAGNETIC_FIELD,
+        TYPE_GYROSCOPE      = ASENSOR_TYPE_GYROSCOPE,
+        TYPE_LIGHT          = ASENSOR_TYPE_LIGHT,
+        TYPE_PROXIMITY      = ASENSOR_TYPE_PROXIMITY
+    };
+
+    struct uuid_t{
+        union {
+            uint8_t b[16];
+            int64_t i64[2];
+        };
+        uuid_t(const uint8_t (&uuid)[16]) { memcpy(b, uuid, sizeof(b));}
+        uuid_t() : b{0} {}
+    };
+
+    Sensor(const Sensor&) = default;
+    Sensor& operator=(const Sensor&) = default;
+
+    Sensor(const char * name = "");
+    Sensor(struct sensor_t const* hwSensor, int halVersion = 0);
+    Sensor(struct sensor_t const& hwSensor, const uuid_t& uuid, int halVersion = 0);
+    ~Sensor();
+
+    const String8& getName() const;
+    const String8& getVendor() const;
+    int32_t getHandle() const;
+    int32_t getType() const;
+    float getMinValue() const;
+    float getMaxValue() const;
+    float getResolution() const;
+    float getPowerUsage() const;
+    int32_t getMinDelay() const;
+    nsecs_t getMinDelayNs() const;
+    int32_t getVersion() const;
+    uint32_t getFifoReservedEventCount() const;
+    uint32_t getFifoMaxEventCount() const;
+    const String8& getStringType() const;
+    const String8& getRequiredPermission() const;
+    bool isRequiredPermissionRuntime() const;
+    int32_t getRequiredAppOp() const;
+    int32_t getMaxDelay() const;
+    uint32_t getFlags() const;
+    bool isWakeUpSensor() const;
+    bool isDynamicSensor() const;
+    bool hasAdditionalInfo() const;
+    int32_t getHighestDirectReportRateLevel() const;
+    bool isDirectChannelTypeSupported(int32_t sharedMemType) const;
+    int32_t getReportingMode() const;
+
+    // Note that after setId() has been called, getUuid() no longer
+    // returns the UUID.
+    // TODO(b/29547335): Remove getUuid(), add getUuidIndex(), and
+    //     make sure setId() doesn't change the UuidIndex.
+    const uuid_t& getUuid() const;
+    int32_t getId() const;
+    void setId(int32_t id);
+
+    // LightFlattenable protocol
+    inline bool isFixedSize() const { return false; }
+    size_t getFlattenedSize() const;
+    status_t flatten(void* buffer, size_t size) const;
+    status_t unflatten(void const* buffer, size_t size);
+
+private:
+    String8 mName;
+    String8 mVendor;
+    int32_t mHandle;
+    int32_t mType;
+    float   mMinValue;
+    float   mMaxValue;
+    float   mResolution;
+    float   mPower;
+    int32_t mMinDelay;
+    int32_t mVersion;
+    uint32_t mFifoReservedEventCount;
+    uint32_t mFifoMaxEventCount;
+    String8 mStringType;
+    String8 mRequiredPermission;
+    bool mRequiredPermissionRuntime = false;
+    int32_t mRequiredAppOp;
+    int32_t mMaxDelay;
+    uint32_t mFlags;
+    // TODO(b/29547335): Get rid of this field and replace with an index.
+    //     The index will be into a separate global vector of UUIDs.
+    //     Also add an mId field (and change flatten/unflatten appropriately).
+    uuid_t  mUuid;
+    static void flattenString8(void*& buffer, size_t& size, const String8& string8);
+    static bool unflattenString8(void const*& buffer, size_t& size, String8& outputString8);
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/sensor/include/sensor/SensorEventQueue.h b/libs/sensor/include/sensor/SensorEventQueue.h
new file mode 100644
index 0000000..84b6ab2
--- /dev/null
+++ b/libs/sensor/include/sensor/SensorEventQueue.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/Timers.h>
+#include <utils/Mutex.h>
+
+#include <sensor/BitTube.h>
+
+// ----------------------------------------------------------------------------
+#define WAKE_UP_SENSOR_EVENT_NEEDS_ACK (1U << 31)
+struct ALooper;
+struct ASensorEvent;
+
+// Concrete types for the NDK
+struct ASensorEventQueue {
+    ALooper* looper;
+};
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+class ISensorEventConnection;
+class Sensor;
+class Looper;
+
+// ----------------------------------------------------------------------------
+
+class SensorEventQueue : public ASensorEventQueue, public RefBase
+{
+public:
+
+    enum { MAX_RECEIVE_BUFFER_EVENT_COUNT = 256 };
+
+    /**
+     * Typical sensor delay (sample period) in microseconds.
+     */
+    // Fastest sampling, system will bound it to minDelay
+    static constexpr int32_t SENSOR_DELAY_FASTEST = 0;
+    // Typical sample period for game, 50Hz;
+    static constexpr int32_t SENSOR_DELAY_GAME = 20000;
+    // Typical sample period for UI, 15Hz
+    static constexpr int32_t SENSOR_DELAY_UI = 66667;
+    // Default sensor sample period
+    static constexpr int32_t SENSOR_DELAY_NORMAL = 200000;
+
+    SensorEventQueue(const sp<ISensorEventConnection>& connection);
+    virtual ~SensorEventQueue();
+    virtual void onFirstRef();
+
+    int getFd() const;
+
+    static ssize_t write(const sp<BitTube>& tube,
+            ASensorEvent const* events, size_t numEvents);
+
+    ssize_t read(ASensorEvent* events, size_t numEvents);
+
+    status_t waitForEvent() const;
+    status_t wake() const;
+
+    status_t enableSensor(Sensor const* sensor) const;
+    status_t enableSensor(Sensor const* sensor, int32_t samplingPeriodUs) const;
+    status_t disableSensor(Sensor const* sensor) const;
+    status_t setEventRate(Sensor const* sensor, nsecs_t ns) const;
+
+    // these are here only to support SensorManager.java
+    status_t enableSensor(int32_t handle, int32_t samplingPeriodUs, int maxBatchReportLatencyUs,
+                          int reservedFlags) const;
+    status_t disableSensor(int32_t handle) const;
+    status_t flush() const;
+    // Send an ack for every wake_up sensor event that is set to WAKE_UP_SENSOR_EVENT_NEEDS_ACK.
+    void sendAck(const ASensorEvent* events, int count);
+
+    status_t injectSensorEvent(const ASensorEvent& event);
+private:
+    sp<Looper> getLooper() const;
+    sp<ISensorEventConnection> mSensorEventConnection;
+    sp<BitTube> mSensorChannel;
+    mutable Mutex mLock;
+    mutable sp<Looper> mLooper;
+    ASensorEvent* mRecBuffer;
+    size_t mAvailable;
+    size_t mConsumed;
+    uint32_t mNumAcksToSend;
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/sensor/include/sensor/SensorManager.h b/libs/sensor/include/sensor/SensorManager.h
new file mode 100644
index 0000000..a3d9741
--- /dev/null
+++ b/libs/sensor/include/sensor/SensorManager.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_GUI_SENSOR_MANAGER_H
+#define ANDROID_GUI_SENSOR_MANAGER_H
+
+#include <map>
+#include <unordered_map>
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <binder/IBinder.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+
+#include <utils/Errors.h>
+#include <utils/StrongPointer.h>
+#include <utils/Vector.h>
+#include <utils/String8.h>
+
+#include <sensor/SensorEventQueue.h>
+
+// ----------------------------------------------------------------------------
+// Concrete types for the NDK
+struct ASensorManager { };
+
+struct native_handle;
+typedef struct native_handle native_handle_t;
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+class ISensorServer;
+class Sensor;
+class SensorEventQueue;
+// ----------------------------------------------------------------------------
+
+class SensorManager : public ASensorManager
+{
+public:
+    static SensorManager& getInstanceForPackage(const String16& packageName);
+    ~SensorManager();
+
+    ssize_t getSensorList(Sensor const* const** list);
+    ssize_t getDynamicSensorList(Vector<Sensor>& list);
+    Sensor const* getDefaultSensor(int type);
+    sp<SensorEventQueue> createEventQueue(String8 packageName = String8(""), int mode = 0);
+    bool isDataInjectionEnabled();
+    int createDirectChannel(size_t size, int channelType, const native_handle_t *channelData);
+    void destroyDirectChannel(int channelNativeHandle);
+    int configureDirectChannel(int channelNativeHandle, int sensorHandle, int rateLevel);
+
+private:
+    // DeathRecipient interface
+    void sensorManagerDied();
+
+    SensorManager(const String16& opPackageName);
+    status_t assertStateLocked();
+
+private:
+    static Mutex sLock;
+    static std::map<String16, SensorManager*> sPackageInstances;
+
+    Mutex mLock;
+    sp<ISensorServer> mSensorServer;
+    Sensor const** mSensorList;
+    Vector<Sensor> mSensors;
+    sp<IBinder::DeathRecipient> mDeathObserver;
+    const String16 mOpPackageName;
+    std::unordered_map<int, sp<ISensorEventConnection>> mDirectConnection;
+    int32_t mDirectConnectionHandle;
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_GUI_SENSOR_MANAGER_H
diff --git a/libs/sensor/tests/Android.bp b/libs/sensor/tests/Android.bp
new file mode 100644
index 0000000..9d530fc
--- /dev/null
+++ b/libs/sensor/tests/Android.bp
@@ -0,0 +1,29 @@
+// Copyright 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_test {
+    name: "libsensor_test",
+
+    clang: true,
+
+    srcs: [
+        "Sensor_test.cpp",
+    ],
+
+    shared_libs: [
+        "liblog",
+        "libsensor",
+        "libutils",
+    ],
+}
diff --git a/libs/sensor/tests/Sensor_test.cpp b/libs/sensor/tests/Sensor_test.cpp
new file mode 100644
index 0000000..ede20c9
--- /dev/null
+++ b/libs/sensor/tests/Sensor_test.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "Sensor_test"
+
+#include <sensor/Sensor.h>
+#include <hardware/sensors.h>
+#include <utils/Errors.h>
+
+#include <gtest/gtest.h>
+
+namespace android {
+
+// Returns true if the two sensors have the same attributes. Does not compare
+// UUID since that should not be transmitted via flatten/unflatten.
+static bool sensorsMatch(const Sensor& a, const Sensor& b) {
+    return a.getName() == b.getName () &&
+        a.getVendor() == b.getVendor () &&
+        a.getHandle() == b.getHandle () &&
+        a.getType() == b.getType () &&
+        a.getMinValue() == b.getMinValue () &&
+        a.getMaxValue() == b.getMaxValue () &&
+        a.getResolution() == b.getResolution () &&
+        a.getPowerUsage() == b.getPowerUsage () &&
+        a.getMinDelay() == b.getMinDelay () &&
+        a.getMinDelayNs() == b.getMinDelayNs () &&
+        a.getVersion() == b.getVersion () &&
+        a.getFifoReservedEventCount() == b.getFifoReservedEventCount () &&
+        a.getFifoMaxEventCount() == b.getFifoMaxEventCount () &&
+        a.getStringType() == b.getStringType () &&
+        a.getRequiredPermission() == b.getRequiredPermission () &&
+        a.isRequiredPermissionRuntime() == b.isRequiredPermissionRuntime () &&
+        a.getRequiredAppOp() == b.getRequiredAppOp () &&
+        a.getMaxDelay() == b.getMaxDelay () &&
+        a.getFlags() == b.getFlags () &&
+        a.isWakeUpSensor() == b.isWakeUpSensor () &&
+        a.isDynamicSensor() == b.isDynamicSensor () &&
+        a.hasAdditionalInfo() == b.hasAdditionalInfo () &&
+        a.getReportingMode() == b.getReportingMode();
+}
+
+// Creates and returns a sensor_t struct with some default values filled in.
+static sensor_t getTestSensorT() {
+    sensor_t hwSensor = {};
+    hwSensor.name = "Test Sensor";
+    hwSensor.vendor = "Test Vendor";
+    hwSensor.version = 1;
+    hwSensor.handle = 2;
+    hwSensor.type = SENSOR_TYPE_ACCELEROMETER;
+    hwSensor.maxRange = 10.f;
+    hwSensor.resolution = 1.f;
+    hwSensor.power = 5.f;
+    hwSensor.minDelay = 1000;
+    hwSensor.fifoReservedEventCount = 50;
+    hwSensor.fifoMaxEventCount = 100;
+    hwSensor.stringType = SENSOR_STRING_TYPE_ACCELEROMETER;
+    hwSensor.requiredPermission = "";
+    hwSensor.maxDelay = 5000;
+    hwSensor.flags = SENSOR_FLAG_CONTINUOUS_MODE;
+    return hwSensor;
+}
+
+TEST(SensorTest, FlattenAndUnflatten) {
+    sensor_t hwSensor = getTestSensorT();
+    Sensor sensor1(&hwSensor, SENSORS_DEVICE_API_VERSION_1_4);
+    Sensor sensor2;
+
+    std::vector<uint8_t> buffer(sensor1.getFlattenedSize());
+    ASSERT_EQ(OK, sensor1.flatten(buffer.data(), buffer.size()));
+    ASSERT_EQ(OK, sensor2.unflatten(buffer.data(), buffer.size()));
+
+    EXPECT_TRUE(sensorsMatch(sensor1, sensor2));
+}
+
+} // namespace android