Exact copy of GCE sensors

Change-Id: If201111cdc3cd327603da3e14f7361f154a0d938
diff --git a/guest/hals/sensors/Android.mk b/guest/hals/sensors/Android.mk
new file mode 100644
index 0000000..a9342c6
--- /dev/null
+++ b/guest/hals/sensors/Android.mk
@@ -0,0 +1,57 @@
+# Copyright (C) 2016 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.
+
+LOCAL_PATH := $(call my-dir)
+
+# HAL module implemenation stored in
+# hw/<SENSORS_HARDWARE_MODULE_ID>.<ro.hardware>.so
+include $(CLEAR_VARS)
+
+ifeq (0, $(shell test $(PLATFORM_SDK_VERSION) -ge 21; echo $$?))
+LOCAL_MODULE_RELATIVE_PATH := hw
+else
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
+endif
+LOCAL_MULTILIB := first
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SHARED_LIBRARIES := \
+    $(GCE_STLPORT_LIBS) \
+    liblog \
+    libcutils \
+    libgcecutils
+
+LOCAL_SRC_FILES := \
+    sensors_hal.cpp \
+    gce_sensors.cpp \
+    sensors.cpp
+
+LOCAL_CFLAGS := -DLOG_TAG=\"GceSensors\" \
+    $(GCE_VERSION_CFLAGS) \
+    -Werror -Wall -Wno-missing-field-initializers -Wno-unused-parameter
+
+LOCAL_C_INCLUDES := \
+    $(GCE_STLPORT_INCLUDES) \
+    device/google/gce/include \
+    system/extras
+
+LOCAL_STATIC_LIBRARIES := \
+    libgcemetadata \
+    libcutils \
+    $(GCE_STLPORT_STATIC_LIBS)
+
+LOCAL_MODULE := sensors.$(VIRTUAL_HARDWARE_TYPE)
+LOCAL_VENDOR_MODULE := true
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/guest/hals/sensors/gce_sensors.cpp b/guest/hals/sensors/gce_sensors.cpp
new file mode 100644
index 0000000..2f7d4aa
--- /dev/null
+++ b/guest/hals/sensors/gce_sensors.cpp
@@ -0,0 +1,529 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+// Google Compute Engine (GCE) Sensors HAL - Sensors HAL Interface
+
+#include <api_level_fixes.h>
+#include <cstdint>
+
+#include <cutils/properties.h>
+#include <cutils/sockets.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/system_properties.h>
+#include <unistd.h>
+
+#include <algorithm>
+
+#include <SharedSelect.h>
+#include <Thunkers.h>
+#include <gce_sensors_message.h>
+#include <remoter_framework_pkt.h>
+#include "gce_sensors.h"
+#include "sensors_hal.h"
+
+using avd::LockGuard;
+using avd::Mutex;
+using avd::time::Milliseconds;
+using avd::time::MonotonicTimePoint;
+using avd::time::Nanoseconds;
+
+namespace avd {
+
+namespace {
+template <typename F>
+struct HWDeviceThunker : ThunkerBase<hw_device_t, GceSensors, F> {};
+template <typename F>
+struct SensorsThunker : ThunkerBase<sensors_poll_device_t, GceSensors, F> {};
+template <typename F>
+struct SensorsThunker1 : ThunkerBase<sensors_poll_device_1, GceSensors, F> {};
+template <typename F>
+struct SensorsThreadThunker : ThunkerBase<void, GceSensors, F> {};
+}
+
+int GceSensors::total_sensor_count_ = -1;
+SensorInfo* GceSensors::sensor_infos_ = NULL;
+const int GceSensors::kInjectedEventWaitPeriods = 3;
+const Nanoseconds GceSensors::kInjectedEventWaitTime =
+    Nanoseconds(Milliseconds(20));
+
+GceSensors::GceSensors()
+  : sensors_poll_device_1(), deadline_change_(&sensor_state_lock_) {
+  if (total_sensor_count_ == -1) {
+    RegisterSensors();
+  }
+
+  // Create a pair of FDs that would be used to control the
+  // receiver thread.
+  if (control_sender_socket_->IsOpen() || control_receiver_socket_->IsOpen()) {
+    ALOGE("%s: Receiver control FDs are opened", __FUNCTION__);
+  }
+  if (!avd::SharedFD::Pipe(&control_receiver_socket_,
+                           &control_sender_socket_)) {
+    ALOGE("%s: Unable to create thread control FDs: %d -> %s", __FUNCTION__,
+          errno, strerror(errno));
+  }
+
+  // Create the correct number of holding buffers for this client.
+  sensor_states_.resize(total_sensor_count_);
+  int i;
+  for (i = 0; i < total_sensor_count_; i++) {
+    sensor_states_[i] = new SensorState(sensor_infos_[i]);
+  }
+}
+
+GceSensors::~GceSensors() {
+  int i;
+  for (i = 0; i < total_sensor_count_; i++) {
+    delete sensor_states_[i];
+  }
+}
+
+int GceSensors::GetSensorsList(struct sensors_module_t* /*module*/,
+                               struct sensor_t const** list) {
+  *list = sensor_infos_;
+  return total_sensor_count_;
+}
+
+int GceSensors::SetOperationMode(unsigned int /* is_loopback_mode */) {
+  return -EINVAL;
+}
+
+int GceSensors::Open(const struct hw_module_t* module, const char* name,
+                     struct hw_device_t** device) {
+  int status = -EINVAL;
+
+  if (!strcmp(name, SENSORS_HARDWARE_POLL)) {
+    // Create a new GceSensors object and set all the fields/functions
+    // to their default values.
+    GceSensors* rval = new GceSensors;
+
+    rval->common.tag = HARDWARE_DEVICE_TAG;
+    rval->common.version = GCE_SENSOR_DEVICE_VERSION;
+    rval->common.module = (struct hw_module_t*)module;
+    rval->common.close = HWDeviceThunker<int()>::call<&GceSensors::Close>;
+    rval->poll =
+        SensorsThunker<int(sensors_event_t*, int)>::call<&GceSensors::Poll>;
+    rval->activate = SensorsThunker<int(int, int)>::call<&GceSensors::Activate>;
+    rval->setDelay =
+        SensorsThunker<int(int, int64_t)>::call<&GceSensors::SetDelay>;
+#if GCE_SENSORS_DEVICE_API_VERSION_ATLEAST(1_0)
+    rval->batch = SensorsThunker1<int(int, int, int64_t,
+                                      int64_t)>::call<&GceSensors::Batch>;
+#endif
+#if GCE_SENSORS_DEVICE_API_VERSION_ATLEAST(1_1)
+    rval->flush = SensorsThunker1<int(int)>::call<&GceSensors::Flush>;
+#endif
+#if GCE_SENSORS_DEVICE_API_VERSION_ATLEAST(1_4)
+    rval->inject_sensor_data = SensorsThunker1<int(
+        const sensors_event_t*)>::call<&GceSensors::InjectSensorData>;
+#endif
+
+    // Spawn a thread to listen for incoming data from the remoter.
+    int err = pthread_create(
+        &rval->receiver_thread_, NULL,
+        SensorsThreadThunker<void*()>::call<&GceSensors::Receiver>, rval);
+    if (err) {
+      ALOGE("GceSensors::%s: Unable to start receiver thread (%s)",
+            __FUNCTION__, strerror(err));
+    }
+
+    *device = &rval->common;
+    status = 0;
+  }
+  return status;
+}
+
+int GceSensors::Close() {
+  // Make certain the receiver thread wakes up.
+  SensorControlMessage msg;
+  msg.message_type = THREAD_STOP;
+  SendControlMessage(msg);
+  pthread_join(receiver_thread_, NULL);
+  delete this;
+  return 0;
+}
+
+int GceSensors::Activate(int handle, int enabled) {
+  if (handle < 0 || handle >= total_sensor_count_) {
+    ALOGE("GceSensors::%s: Bad handle %d", __FUNCTION__, handle);
+    return -1;
+  }
+
+  {
+    LockGuard<Mutex> guard(sensor_state_lock_);
+    // Update the report deadline, if changed.
+    if (enabled && !sensor_states_[handle]->enabled_) {
+      sensor_states_[handle]->deadline_ =
+          MonotonicTimePoint::Now() + sensor_states_[handle]->sampling_period_;
+    } else if (!enabled && sensor_states_[handle]->enabled_) {
+      sensor_states_[handle]->deadline_ = SensorState::kInfinity;
+    }
+    sensor_states_[handle]->enabled_ = enabled;
+    UpdateDeadline();
+  }
+
+  D("sensor_activate(): handle %d, enabled %d", handle, enabled);
+  if (!UpdateRemoterState(handle)) {
+    ALOGE("Failed to notify remoter about new sensor enable/disable.");
+  }
+  return 0;
+}
+
+int GceSensors::SetDelay(int handle, int64_t sampling_period_ns) {
+  if (handle < 0 || handle >= total_sensor_count_) {
+    ALOGE("GceSensors::%s: Bad handle %d", __FUNCTION__, handle);
+    return -1;
+  }
+  int64_t min_delay_ns = sensor_infos_[handle].minDelay * 1000;
+  if (sampling_period_ns < min_delay_ns) {
+    sampling_period_ns = min_delay_ns;
+  }
+
+  {
+    LockGuard<Mutex> guard(sensor_state_lock_);
+    sensor_states_[handle]->deadline_ -=
+        sensor_states_[handle]->sampling_period_;
+    sensor_states_[handle]->sampling_period_ = Nanoseconds(sampling_period_ns);
+    sensor_states_[handle]->deadline_ +=
+        sensor_states_[handle]->sampling_period_;
+    // If our sampling period has decreased, our deadline
+    // could have already passed. If so, report immediately, but not in the
+    // past.
+    MonotonicTimePoint now = MonotonicTimePoint::Now();
+    if (sensor_states_[handle]->deadline_ < now) {
+      sensor_states_[handle]->deadline_ = now;
+    }
+    UpdateDeadline();
+  }
+
+  D("sensor_set_delay(): handle %d, delay (ms) %" PRId64, handle,
+    Milliseconds(Nanoseconds(sampling_period_ns)).count());
+  if (!UpdateRemoterState(handle)) {
+    ALOGE("Failed to notify remoter about new sensor delay.");
+  }
+  return 0;
+}
+
+int GceSensors::Poll(sensors_event_t* data, int count_unsafe) {
+  if (count_unsafe <= 0) {
+    ALOGE("Framework polled with bad count (%d)", count_unsafe);
+    return -1;
+  }
+  size_t count = size_t(count_unsafe);
+
+  // Poll will block until 1 of 2 things happens:
+  //    1. The next deadline for some active sensor
+  //        occurs.
+  //    2. The next deadline changes (either because
+  //        a sensor was activated/deactivated or its
+  //        delay changed).
+  // In both cases, any sensors whose report deadlines
+  // have passed will report their data (or mock data),
+  // and poll will either return (if at least one deadline
+  // has passed), or repeat by blocking until the next deadline.
+  LockGuard<Mutex> guard(sensor_state_lock_);
+  current_deadline_ = UpdateDeadline();
+  // Sleep until we have something to report
+  while (!fifo_.size()) {
+    deadline_change_.WaitUntil(current_deadline_);
+    current_deadline_ = UpdateDeadline();
+  }
+  // Copy the events from the buffer
+  int num_copied = std::min(fifo_.size(), count);
+  FifoType::iterator first_uncopied = fifo_.begin() + num_copied;
+  std::copy(fifo_.begin(), first_uncopied, data);
+  fifo_.erase(fifo_.begin(), first_uncopied);
+  D("Reported %d sensor events. First: %d %f %f %f", num_copied, data->sensor,
+    data->data[0], data->data[1], data->data[2]);
+  return num_copied;
+}
+
+
+void *GceSensors::Receiver() {
+  // Initialize the server.
+  sensor_listener_socket_ = avd::SharedFD::SocketSeqPacketServer(
+      gce_sensors_message::kSensorsHALSocketName, 0777);
+  if (!sensor_listener_socket_->IsOpen()) {
+    ALOGE("GceSensors::%s: Could not listen for sensor connections. (%s).",
+          __FUNCTION__, sensor_listener_socket_->StrError());
+    return NULL;
+  }
+  D("GceSensors::%s: Listening for sensor connections at %s", __FUNCTION__,
+    gce_sensors_message::kSensorsHALSocketName);
+  // Announce that we are ready for the remoter to connect.
+  if (!NotifyRemoter()) {
+    ALOGI("Failed to notify remoter that HAL is ready.");
+  } else {
+    ALOGI("Notified remoter that HAL is ready.");
+  }
+
+  typedef std::vector<avd::SharedFD> FDVec;
+  FDVec connected;
+  // Listen for incoming sensor data and control messages
+  // from the HAL.
+  while (true) {
+    avd::SharedFDSet fds;
+    for (FDVec::iterator it = connected.begin(); it != connected.end(); ++it) {
+      fds.Set(*it);
+    }
+    fds.Set(control_receiver_socket_);
+    fds.Set(sensor_listener_socket_);
+    int res = avd::Select(&fds, NULL, NULL, NULL);
+    if (res == -1) {
+      ALOGE("%s: select returned %d and failed %d -> %s", __FUNCTION__, res,
+            errno, strerror(errno));
+      break;
+    } else if (res == 0) {
+      ALOGE("%s: select timed out", __FUNCTION__);
+      break;
+    } else if (fds.IsSet(sensor_listener_socket_)) {
+      connected.push_back(avd::SharedFD::Accept(*sensor_listener_socket_));
+      ALOGI("GceSensors::%s: new client connected", __FUNCTION__);
+    } else if (fds.IsSet(control_receiver_socket_)) {
+      // We received a control message.
+      SensorControlMessage msg;
+      int res =
+          control_receiver_socket_->Read(&msg, sizeof(SensorControlMessage));
+      if (res == -1) {
+        ALOGE("GceSensors::%s: Failed to receive control message.",
+              __FUNCTION__);
+      } else if (res == 0) {
+        ALOGE("GceSensors::%s: Control connection closed.", __FUNCTION__);
+      }
+      if (msg.message_type == SENSOR_STATE_UPDATE) {
+        // Forward the update to the remoter.
+        remoter_request_packet packet;
+        remoter_request_packet_init(&packet, kRemoterSensorState, 0);
+        {
+          LockGuard<Mutex> guard(sensor_state_lock_);
+          packet.params.sensor_state_params.type =
+              sensor_infos_[msg.sensor_handle].type;
+          packet.params.sensor_state_params.enabled =
+              sensor_states_[msg.sensor_handle]->enabled_;
+          packet.params.sensor_state_params.delay_ns =
+              sensor_states_[msg.sensor_handle]->sampling_period_.count();
+          packet.params.sensor_state_params.handle = msg.sensor_handle;
+        }
+        struct msghdr msg;
+        iovec msg_iov[1];
+        msg_iov[0].iov_base = &packet;
+        msg_iov[0].iov_len = sizeof(remoter_request_packet);
+        msg.msg_name = NULL;
+        msg.msg_namelen = 0;
+        msg.msg_iov = msg_iov;
+        msg.msg_iovlen = arraysize(msg_iov);
+        msg.msg_control = NULL;
+        msg.msg_controllen = 0;
+        msg.msg_flags = 0;
+
+        for (FDVec::iterator it = connected.begin(); it != connected.end();
+             ++it) {
+          avd::SharedFD &fd = *it;
+          if (fd->SendMsg(&msg, 0) == -1) {
+            ALOGE("GceSensors::%s. Could not send sensor state (%s).",
+                  __FUNCTION__, fd->StrError());
+          }
+        }
+      }
+      if (msg.message_type == THREAD_STOP) {
+        D("Received terminate control message.");
+        return NULL;
+      }
+    } else {
+      for (FDVec::iterator it = connected.begin(); it != connected.end();
+           ++it) {
+        avd::SharedFD &fd = *it;
+        if (fds.IsSet(fd)) {
+          // We received a sensor update from remoter.
+          sensors_event_t event;
+          struct msghdr msg;
+          iovec msg_iov[1];
+          msg_iov[0].iov_base = &event;
+          msg_iov[0].iov_len = sizeof(event);
+          msg.msg_name = NULL;
+          msg.msg_namelen = 0;
+          msg.msg_iov = msg_iov;
+          msg.msg_iovlen = arraysize(msg_iov);
+          msg.msg_control = NULL;
+          msg.msg_controllen = 0;
+          msg.msg_flags = 0;
+          int res = fd->RecvMsg(&msg, 0);
+          if (res <= 0) {
+            if (res == 0) {
+              ALOGE("GceSensors::%s: Sensors HAL connection closed.",
+                    __FUNCTION__);
+            } else {
+              ALOGE("GceSensors::%s: Failed to receive sensor message",
+                    __FUNCTION__);
+            }
+            connected.erase(std::find(connected.begin(), connected.end(), fd));
+            break;
+          }
+
+          // We received an event from the remoter.
+          if (event.sensor < 0 || event.sensor >= total_sensor_count_) {
+            ALOGE("Remoter sent us an invalid sensor event! (handle %d)",
+                  event.sensor);
+            connected.erase(std::find(connected.begin(), connected.end(), fd));
+            break;
+          }
+
+          D("Received sensor event: %d %f %f %f", event.sensor, event.data[0],
+            event.data[1], event.data[2]);
+
+          {
+            LockGuard<Mutex> guard(sensor_state_lock_);
+            // Increase the delay so that the HAL knows
+            // it shouldn't report on its own for a while.
+            SensorState *holding_buffer = sensor_states_[event.sensor];
+            int wait_periods =
+                std::max(kInjectedEventWaitPeriods,
+                         (int)(kInjectedEventWaitTime.count() /
+                               holding_buffer->sampling_period_.count()));
+            holding_buffer->deadline_ =
+                MonotonicTimePoint::Now() +
+                holding_buffer->sampling_period_ * wait_periods;
+            holding_buffer->event_.data[0] = event.data[0];
+            holding_buffer->event_.data[1] = event.data[1];
+            holding_buffer->event_.data[2] = event.data[2];
+            // Signal the HAL to report the newly arrived event.
+            fifo_.push_back(event);
+            deadline_change_.NotifyOne();
+          }
+        }
+      }
+    }
+  }
+  return NULL;
+}
+
+bool GceSensors::NotifyRemoter() {
+  remoter_request_packet packet;
+  remoter_request_packet_init(&packet, kRemoterHALReady, 0);
+  packet.send_response = 0;
+  strncpy(packet.params.hal_ready_params.unix_socket,
+          gce_sensors_message::kSensorsHALSocketName,
+          sizeof(packet.params.hal_ready_params.unix_socket));
+  AutoCloseFileDescriptor remoter_socket(remoter_connect());
+  if (remoter_socket.IsError()) {
+    D("GceSensors::%s: Could not connect to remoter to notify ready (%s).",
+      __FUNCTION__, strerror(errno));
+    return false;
+  }
+  int err =
+      remoter_do_single_request_with_socket(remoter_socket, &packet, NULL);
+  if (err == -1) {
+    D("GceSensors::%s: Notify remoter ready: Failed after connect (%s).",
+      __FUNCTION__, strerror(errno));
+    return false;
+  }
+  D("GceSensors::%s: Notify remoter ready Succeeded.", __FUNCTION__);
+  return true;
+}
+
+static bool CompareTimestamps(const sensors_event_t& a,
+                              const sensors_event_t& b) {
+  return a.timestamp < b.timestamp;
+}
+
+MonotonicTimePoint GceSensors::UpdateDeadline() {
+  // Get the minimum of all the current deadlines.
+  MonotonicTimePoint now = MonotonicTimePoint::Now();
+  MonotonicTimePoint min = SensorState::kInfinity;
+  int i = 0;
+  bool sort_fifo = false;
+
+  for (i = 0; i < total_sensor_count_; i++) {
+    SensorState* holding_buffer = sensor_states_[i];
+    // Ignore disabled sensors.
+    if (!holding_buffer->enabled_) {
+      continue;
+    }
+    while (holding_buffer->deadline_ < now) {
+      sensors_event_t data = holding_buffer->event_;
+      data.timestamp = holding_buffer->deadline_.SinceEpoch().count();
+      fifo_.push_back(data);
+      holding_buffer->deadline_ += holding_buffer->sampling_period_;
+      sort_fifo = true;
+    }
+    // Now check if we should update the wake time based on the next event
+    // from this sensor.
+    if (sensor_states_[i]->deadline_ < min) {
+      min = sensor_states_[i]->deadline_;
+    }
+  }
+  // We added one or more sensor readings, so do a sort.
+  // This is likely to be cheaper than a traditional priority queue because
+  // a priority queue would try to keep its state correct for each addition.
+  if (sort_fifo) {
+    std::sort(fifo_.begin(), fifo_.end(), CompareTimestamps);
+  }
+  // If we added events or the deadline is lower notify the thread in Poll().
+  // If the deadline went up, don't do anything.
+  if (fifo_.size() || (min < current_deadline_)) {
+    deadline_change_.NotifyOne();
+  }
+  return min;
+}
+
+bool GceSensors::UpdateRemoterState(int handle) {
+  SensorControlMessage msg;
+  msg.message_type = SENSOR_STATE_UPDATE;
+  msg.sensor_handle = handle;
+  return SendControlMessage(msg);
+}
+
+bool GceSensors::SendControlMessage(SensorControlMessage msg) {
+  if (!control_sender_socket_->IsOpen()) {
+    ALOGE("%s: Can't send control message %d, control socket not open.",
+          __FUNCTION__, msg.message_type);
+    return false;
+  }
+  if (control_sender_socket_->Write(&msg, sizeof(SensorControlMessage)) == -1) {
+    ALOGE("GceSensors::%s. Could not send control message %d (%s).",
+          __FUNCTION__, msg.message_type, control_sender_socket_->StrError());
+    return false;
+  }
+  return true;
+}
+
+int GceSensors::RegisterSensors() {
+  if (total_sensor_count_ != -1) {
+    return -1;
+  }
+  total_sensor_count_ = 9;
+  sensor_infos_ = new SensorInfo[total_sensor_count_];
+  sensor_infos_[sensors_constants::kAccelerometerHandle] =
+      AccelerometerSensor();
+  sensor_infos_[sensors_constants::kGyroscopeHandle] = GyroscopeSensor();
+  sensor_infos_[sensors_constants::kLightHandle] = LightSensor();
+  sensor_infos_[sensors_constants::kMagneticFieldHandle] =
+      MagneticFieldSensor();
+  sensor_infos_[sensors_constants::kPressureHandle] = PressureSensor();
+  sensor_infos_[sensors_constants::kProximityHandle] = ProximitySensor();
+  sensor_infos_[sensors_constants::kAmbientTempHandle] = AmbientTempSensor();
+  sensor_infos_[sensors_constants::kDeviceTempHandle] = DeviceTempSensor();
+  sensor_infos_[sensors_constants::kRelativeHumidityHandle] =
+      RelativeHumiditySensor();
+  int i;
+  for (i = 0; i < total_sensor_count_; i++) {
+    D("Found sensor %s with handle %d", sensor_infos_[i].name,
+      sensor_infos_[i].handle);
+  }
+  return total_sensor_count_;
+}
+
+}  // namespace avd
diff --git a/guest/hals/sensors/gce_sensors.h b/guest/hals/sensors/gce_sensors.h
new file mode 100644
index 0000000..b06f0d1
--- /dev/null
+++ b/guest/hals/sensors/gce_sensors.h
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+// Google Compute Engine (GCE) Sensors HAL - Sensors HAL Interface
+#ifndef DEVICE_GOOGLE_GCE_SENSORS_GCE_SENSORS_H
+#define DEVICE_GOOGLE_GCE_SENSORS_GCE_SENSORS_H
+
+#include <vector>
+
+#include <Pthread.h>
+#include <SharedFD.h>
+
+#include "remoter_framework_pkt.h"
+
+#include "sensors_hal.h"
+#include "sensors.h"
+
+namespace avd {
+
+// Used for sending control messages to the receiver thread.
+// The sensor_handle field may be left unused if it is not needed.
+enum ControlMessageType {
+  THREAD_STOP,
+  SENSOR_STATE_UPDATE
+};
+typedef struct {
+  ControlMessageType message_type;
+  uint8_t sensor_handle;
+} SensorControlMessage;
+
+#if GCE_SENSORS_DEVICE_API_VERSION_ATLEAST(1_0)
+// Last updated to HAL 1.4
+// Version history:
+//   Before jb, jb-mr1 SENSORS_DEVICE_API_VERSION_0_1 (no version in sensors.h)
+//   jb-mr2: SENSORS_DEVICE_API_VERSION_1_0
+//   k: SENSORS_DEVICE_API_VERSION_1_1
+//   l, l-mr1: SENSORS_DEVICE_API_VERSION_1_3
+//   m, n, n-mr1: SENSORS_DEVICE_API_VERSION_1_4
+#else
+// Pre-1.0 sensors do not define the sensors_poll_device_1 type.
+typedef sensors_poll_device_t sensors_poll_device_1;
+#endif
+
+class GceSensors : public sensors_poll_device_1 {
+ public:
+  GceSensors();
+  ~GceSensors();
+
+  /**
+   ** SENSOR HAL API FUNCTIONS FOR MODULE
+   **/
+
+  // Gets a list of all supported sensors and stores in list.
+  // Returns the number of supported sensors.
+  static int GetSensorsList(struct sensors_module_t* module,
+    struct sensor_t const** list);
+
+  // Place the module in a specific mode. The following modes are defined
+  //
+  //  0 - Normal operation. Default state of the module.
+  //  1 - Loopback mode. Data is injected for the supported
+  //      sensors by the sensor service in this mode.
+  // @return 0 on success
+  //         -EINVAL if requested mode is not supported
+  //         -EPERM if operation is not allowed
+  static int SetOperationMode(unsigned int mode);
+
+
+  /**
+   ** SENSOR HAL API FUNCTIONS FOR DEVICE
+   **/
+  // Opens the device.
+  static int Open(const struct hw_module_t* module, const char* name,
+    struct hw_device_t** device);
+
+  // Closes the device, closing all sensors.
+  int Close();
+
+  // Activate (or deactivate) the sensor with the given handle.
+  //
+  // One-shot sensors deactivate themselves automatically upon receiving an
+  // event, and they must still accept to be deactivated through a call to
+  // activate(..., enabled=0).
+  // Non-wake-up sensors never prevent the SoC from going into suspend mode;
+  // that is, the HAL shall not hold a partial wake-lock on behalf of
+  // applications.
+  //
+  // If enabled is 1 and the sensor is already activated, this function is a
+  // no-op and succeeds.
+  //
+  // If enabled is 0 and the sensor is already deactivated, this function is a
+  // no-op and succeeds.
+  //
+  // This function returns 0 on success and a negative error number otherwise.
+  int Activate(int handle, int enabled);
+
+  // Sets the delay (in ns) for the sensor with the given handle.
+  // Deprecated as of HAL 1.1
+  // Called after activate()
+  int SetDelay(int handle, int64_t sampling_period_ns);
+
+  // Returns an array of sensor data by filling the data argument.
+  // This function must block until events are available. It will return
+  // the number of events read on success, or a negative number in case of
+  // an error.
+  int Poll(sensors_event_t* data, int count);
+
+#if GCE_SENSORS_DEVICE_API_VERSION_ATLEAST(1_0)
+  // Sets a sensor’s parameters, including sampling frequency and maximum
+  // report latency. This function can be called while the sensor is
+  // activated, in which case it must not cause any sensor measurements to
+  // be lost: transitioning from one sampling rate to the other cannot cause
+  // lost events, nor can transitioning from a high maximum report latency to
+  // a low maximum report latency.
+  //
+  // Before SENSORS_DEVICE_API_VERSION_1_3, flags included:
+  //   SENSORS_BATCH_DRY_RUN
+  //   SENSORS_BATCH_WAKE_UPON_FIFO_FULL
+  //
+  // After SENSORS_DEVICE_API_VERSION_1_3 see WAKE_UPON_FIFO_FULL
+  // in sensor_t.flags
+  int Batch(int sensor_handle, int flags, int64_t sampling_period_ns,
+            int64_t max_report_latency_ns) {
+    // TODO: Add support for maximum report latency with max_report_latency_ns.
+    return SetDelay(sensor_handle, sampling_period_ns);
+  }
+#endif
+
+#if GCE_SENSORS_DEVICE_API_VERSION_ATLEAST(1_1)
+  // Adds a META_DATA_FLUSH_COMPLETE event (sensors_event_meta_data_t)
+  // to the end of the "batch mode" FIFO for the specified sensor and flushes
+  // the FIFO.
+  //
+  // If the FIFO is empty or if the sensor doesn't support batching (FIFO
+  // size zero), it should return SUCCESS along with a trivial
+  // META_DATA_FLUSH_COMPLETE event added to the event stream. This applies to
+  // all sensors other than one-shot sensors.
+  //
+  // If the sensor is a one-shot sensor, flush must return -EINVAL and not
+  // generate any flush complete metadata.
+  //
+  // If the sensor is not active at the time flush() is called, flush() should
+  // return -EINVAL.
+  int Flush(int sensor_handle) {
+    return -EINVAL;
+  }
+#endif
+
+#if GCE_SENSORS_DEVICE_API_VERSION_ATLEAST(1_4)
+  // Inject a single sensor sample to be to this device.
+  // data points to the sensor event to be injected
+  // @return 0 on success
+  //  -EPERM if operation is not allowed
+  //  -EINVAL if sensor event cannot be injected
+  int InjectSensorData(const sensors_event_t *data) {
+    return -EINVAL;
+  }
+#endif
+
+ private:
+  typedef std::vector<SensorState*> SensorStateVector;
+  typedef std::vector<sensors_event_t> FifoType;
+  // Total number of sensors supported by this HAL.
+  static int total_sensor_count_;
+  // Vector of static sensor information for sensors supported by this HAL.
+  // Indexed by the handle. Length must always be equal to total_sensor_count_.
+  static SensorInfo* sensor_infos_;
+  // Vector of sensor state information, indexed by the handle.
+  // Assumption here is that the sensor handles will start at 0 and be
+  // contiguous up to the number of supported sensors.
+  SensorStateVector sensor_states_;
+  // Keep track of the time when the thread in Poll() is scheduled to wake.
+  avd::time::MonotonicTimePoint current_deadline_;
+
+  // Ordered set of sensor values.
+  // TODO(ghartman): Simulate FIFO overflow.
+  FifoType fifo_;
+  // Thread to handle new connections.
+  pthread_t receiver_thread_;
+  // Socket to receive sensor events on.
+  avd::SharedFD sensor_listener_socket_;
+  // Socket for listener thread to receive control messages.
+  avd::SharedFD control_receiver_socket_;
+  // Socket to send control messages to listener thread.
+  avd::SharedFD control_sender_socket_;
+
+  // Lock to protect shared state, including
+  // sensor_states_ and next_deadline_.
+  // Associated with deadline_change_ condition variable.
+  avd::Mutex sensor_state_lock_;
+  // Condition variable to signal changes in the deadline.
+  avd::ConditionVariable deadline_change_;
+
+  // When events are arriving from a client, we report only
+  // when they arrive, rather than at a fixed cycle. After not
+  // receiving a real event for both a given number of periods
+  // and a given time period, we will give up and resume
+  // sending mock events.
+  const static int kInjectedEventWaitPeriods;
+  const static avd::time::Nanoseconds kInjectedEventWaitTime;
+
+  /**
+   ** UTILITY FUNCTIONS
+   **/
+
+  // Receive data from remoter.
+  void* Receiver();
+
+  // Notifies the remoter that the HAL is awake and ready.
+  inline bool NotifyRemoter();
+
+  // Looks through all active sensor deadlines, and finds the one that
+  // is coming up next. If this is not next_deadline_, then the deadline
+  // has changed. Update it and signal the Poll thread.
+  // This should be called anytime the next deadline may have changed.
+  // Can only be called while holding sensor_state_lock_.
+  // Returns true if the deadline has changed.
+  avd::time::MonotonicTimePoint UpdateDeadline();
+
+  // Sends an update for the sensor with the given handle to the remoter.
+  // Update will be enqueued for receiver, not send immediately.
+  inline bool UpdateRemoterState(int handle);
+
+  // Sends a control event to the listener.
+  inline bool SendControlMessage(SensorControlMessage msg);
+
+  // Populates the list of static sensor info. Returns the number
+  // of sensors supported. Should only be called once.
+  static inline int RegisterSensors();
+
+};
+
+} //namespace avd
+
+#endif
diff --git a/guest/hals/sensors/gce_sensors_message.h b/guest/hals/sensors/gce_sensors_message.h
new file mode 100644
index 0000000..d1c67ac
--- /dev/null
+++ b/guest/hals/sensors/gce_sensors_message.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2016 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 DEVICE_GOOGLE_GCE_INCLUDE_SENSORS_MESSAGE_H_
+#define DEVICE_GOOGLE_GCE_INCLUDE_SENSORS_MESSAGE_H_
+
+#include <hardware/hardware.h>
+#include <hardware/sensors.h>
+
+struct gce_sensors_message : sensors_event_t {
+  static const char* kSensorsHALSocketName;
+};
+
+#endif
diff --git a/guest/hals/sensors/sensors.cpp b/guest/hals/sensors/sensors.cpp
new file mode 100644
index 0000000..b2f2665
--- /dev/null
+++ b/guest/hals/sensors/sensors.cpp
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+// Google Compute Engine (GCE) Sensors HAL - Sensors HAL State
+
+#include <limits>
+
+#include "sensors.h"
+
+namespace avd {
+namespace {
+const avd::time::Milliseconds kDefaultSamplingRate(200);
+
+#if !GCE_SENSORS_DEVICE_API_VERSION_ATLEAST(1_3)
+namespace {
+const int SENSOR_FLAG_WAKE_UP = 0;
+}
+#endif
+
+timespec infinity() {
+  timespec ts;
+  ts.tv_sec = std::numeric_limits<time_t>::max();
+  ts.tv_nsec = 0;
+  return ts;
+}
+}  // namespace
+
+const avd::time::MonotonicTimePoint SensorState::kInfinity =
+    avd::time::MonotonicTimePoint(infinity());
+
+SensorState::SensorState(SensorInfo info)
+    : enabled_(false),
+      event_(),
+      deadline_(kInfinity),
+      sampling_period_(kDefaultSamplingRate) {
+  event_.sensor = info.handle;
+  event_.type = info.type;
+}
+
+SensorInfo::SensorInfo(const char* name, const char* vendor, int version,
+                       int handle, int type, float max_range, float resolution,
+                       float power, int32_t min_delay,
+                       uint32_t fifo_reserved_event_count,
+                       uint32_t fifo_max_event_count, const char* string_type,
+                       const char* required_permission, int32_t max_delay,
+                       uint32_t reporting_mode) {
+  this->name = name;
+  this->vendor = vendor;
+  this->version = version;
+  this->handle = handle;
+  this->type = type;
+  this->maxRange = max_range;
+  this->resolution = resolution;
+  this->power = power;
+  this->minDelay = min_delay;
+#if GCE_SENSORS_DEVICE_API_VERSION_ATLEAST(1_1)
+  this->fifoReservedEventCount = fifo_reserved_event_count;
+  this->fifoMaxEventCount = fifo_max_event_count;
+#endif
+#if GCE_SENSORS_DEVICE_API_VERSION_ATLEAST(1_2)
+  this->stringType = string_type;
+  this->requiredPermission = required_permission;
+#endif
+#if GCE_SENSORS_DEVICE_API_VERSION_ATLEAST(1_3)
+  this->maxDelay = max_delay;
+  this->flags = reporting_mode;
+#endif
+}
+
+namespace sc = sensors_constants;
+
+SensorInfo AccelerometerSensor() {
+  uint32_t flags = sc::kAccelerometerReportingMode |
+      (sc::kAccelerometerIsWakeup ? SENSOR_FLAG_WAKE_UP : 0);
+
+  return SensorInfo(sc::kAccelerometerName, sc::kVendor, sc::kVersion,
+                    sc::kAccelerometerHandle, SENSOR_TYPE_ACCELEROMETER,
+                    sc::kAccelerometerMaxRange, sc::kAccelerometerResolution,
+                    sc::kAccelerometerPower, sc::kAccelerometerMinDelay,
+                    sc::kFifoReservedEventCount, sc::kFifoMaxEventCount,
+                    sc::kAccelerometerStringType, sc::kRequiredPermission,
+                    sc::kMaxDelay, flags);
+}
+
+SensorInfo GyroscopeSensor() {
+  uint32_t flags = sc::kGyroscopeReportingMode |
+      (sc::kGyroscopeIsWakeup ? SENSOR_FLAG_WAKE_UP : 0);
+
+  return SensorInfo(
+      sc::kGyroscopeName, sc::kVendor, sc::kVersion, sc::kGyroscopeHandle,
+      SENSOR_TYPE_GYROSCOPE, sc::kGyroscopeMaxRange, sc::kGyroscopeResolution,
+      sc::kGyroscopePower, sc::kGyroscopeMinDelay, sc::kFifoReservedEventCount,
+      sc::kFifoMaxEventCount, sc::kGyroscopeStringType, sc::kRequiredPermission,
+      sc::kMaxDelay, flags);
+}
+
+SensorInfo LightSensor() {
+  uint32_t flags = sc::kLightReportingMode |
+      (sc::kLightIsWakeup ? SENSOR_FLAG_WAKE_UP : 0);
+
+  return SensorInfo(sc::kLightName, sc::kVendor, sc::kVersion, sc::kLightHandle,
+                    SENSOR_TYPE_LIGHT, sc::kLightMaxRange, sc::kLightResolution,
+                    sc::kLightPower, sc::kLightMinDelay,
+                    sc::kFifoReservedEventCount, sc::kFifoMaxEventCount,
+                    sc::kLightStringType, sc::kRequiredPermission,
+                    sc::kMaxDelay, flags);
+}
+
+SensorInfo MagneticFieldSensor() {
+  uint32_t flags = sc::kMagneticFieldReportingMode |
+      (sc::kMagneticFieldIsWakeup ? SENSOR_FLAG_WAKE_UP : 0);
+
+  return SensorInfo(sc::kMagneticFieldName, sc::kVendor, sc::kVersion,
+                    sc::kMagneticFieldHandle, SENSOR_TYPE_MAGNETIC_FIELD,
+                    sc::kMagneticFieldMaxRange, sc::kMagneticFieldResolution,
+                    sc::kMagneticFieldPower, sc::kMagneticFieldMinDelay,
+                    sc::kFifoReservedEventCount, sc::kFifoMaxEventCount,
+                    sc::kMagneticFieldStringType, sc::kRequiredPermission,
+                    sc::kMaxDelay, flags);
+}
+
+SensorInfo PressureSensor() {
+  uint32_t flags = sc::kPressureReportingMode |
+      (sc::kPressureIsWakeup ? SENSOR_FLAG_WAKE_UP : 0);
+
+  return SensorInfo(
+      sc::kPressureName, sc::kVendor, sc::kVersion, sc::kPressureHandle,
+      SENSOR_TYPE_PRESSURE, sc::kPressureMaxRange, sc::kPressureResolution,
+      sc::kPressurePower, sc::kPressureMinDelay, sc::kFifoReservedEventCount,
+      sc::kFifoMaxEventCount, sc::kPressureStringType, sc::kRequiredPermission,
+      sc::kMaxDelay, flags);
+}
+
+SensorInfo ProximitySensor() {
+  uint32_t flags = sc::kProximityReportingMode |
+      (sc::kProximityIsWakeup ? SENSOR_FLAG_WAKE_UP : 0);
+
+  return SensorInfo(
+      sc::kProximityName, sc::kVendor, sc::kVersion, sc::kProximityHandle,
+      SENSOR_TYPE_PROXIMITY, sc::kProximityMaxRange, sc::kProximityResolution,
+      sc::kProximityPower, sc::kProximityMinDelay, sc::kFifoReservedEventCount,
+      sc::kFifoMaxEventCount, sc::kProximityStringType, sc::kRequiredPermission,
+      sc::kMaxDelay, flags);
+}
+
+SensorInfo AmbientTempSensor() {
+  uint32_t flags = sc::kAmbientTempReportingMode |
+      (sc::kAmbientTempIsWakeup ? SENSOR_FLAG_WAKE_UP : 0);
+
+  return SensorInfo(sc::kAmbientTempName, sc::kVendor, sc::kVersion,
+                    sc::kAmbientTempHandle, SENSOR_TYPE_AMBIENT_TEMPERATURE,
+                    sc::kAmbientTempMaxRange, sc::kAmbientTempResolution,
+                    sc::kAmbientTempPower, sc::kAmbientTempMinDelay,
+                    sc::kFifoReservedEventCount, sc::kFifoMaxEventCount,
+                    sc::kAmbientTempStringType, sc::kRequiredPermission,
+                    sc::kMaxDelay, flags);
+}
+
+SensorInfo DeviceTempSensor() {
+  uint32_t flags = sc::kDeviceTempReportingMode |
+      (sc::kDeviceTempIsWakeup ? SENSOR_FLAG_WAKE_UP : 0);
+
+  return SensorInfo(sc::kDeviceTempName, sc::kVendor, sc::kVersion,
+                    sc::kDeviceTempHandle, SENSOR_TYPE_TEMPERATURE,
+                    sc::kDeviceTempMaxRange, sc::kDeviceTempResolution,
+                    sc::kDeviceTempPower, sc::kDeviceTempMinDelay,
+                    sc::kFifoReservedEventCount, sc::kFifoMaxEventCount,
+                    sc::kDeviceTempStringType, sc::kRequiredPermission,
+                    sc::kMaxDelay, flags);
+}
+
+SensorInfo RelativeHumiditySensor() {
+  uint32_t flags = sc::kRelativeHumidityReportingMode |
+      (sc::kRelativeHumidityIsWakeup ? SENSOR_FLAG_WAKE_UP : 0);
+
+  return SensorInfo(sc::kRelativeHumidityName, sc::kVendor, sc::kVersion,
+                    sc::kRelativeHumidityHandle, SENSOR_TYPE_RELATIVE_HUMIDITY,
+                    sc::kRelativeHumidityMaxRange,
+                    sc::kRelativeHumidityResolution, sc::kRelativeHumidityPower,
+                    sc::kRelativeHumidityMinDelay, sc::kFifoReservedEventCount,
+                    sc::kFifoMaxEventCount, sc::kRelativeHumidityStringType,
+                    sc::kRequiredPermission, sc::kMaxDelay,
+                    flags);
+}
+
+}  // namespace avd
diff --git a/guest/hals/sensors/sensors.h b/guest/hals/sensors/sensors.h
new file mode 100644
index 0000000..7b7c402
--- /dev/null
+++ b/guest/hals/sensors/sensors.h
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+// Google Compute Engine (GCE) Sensors HAL - Sensors HAL State
+#ifndef DEVICE_GOOGLE_GCE_SENSORS_SENSORS_H
+#define DEVICE_GOOGLE_GCE_SENSORS_SENSORS_H
+
+#include <api_level_fixes.h>
+#include "MonotonicTime.h"
+#include "sensors_hal.h"
+
+namespace avd {
+
+// Stores static information about a sensor.
+// Must be completely compatible with sensor_t (i.e. no additional
+// information or virtual functions)
+// so we can cast a list of SensorInfo to a list of sensor_t.
+class SensorInfo : public sensor_t {
+ public:
+  // Dummy, empty set of sensor information (value-initialized).
+  SensorInfo() : sensor_t() {}
+
+ private:
+  SensorInfo(const char* name, const char* vendor, int version, int handle,
+             int type, float max_range, float resolution, float power,
+             int32_t min_delay, uint32_t fifo_reserved_event_count,
+             uint32_t fifo_max_event_count, const char* string_type,
+             const char* required_permission, int32_t max_delay,
+             uint32_t reporting_mode);
+
+  friend SensorInfo AccelerometerSensor();
+  friend SensorInfo GyroscopeSensor();
+  friend SensorInfo LightSensor();
+  friend SensorInfo MagneticFieldSensor();
+  friend SensorInfo PressureSensor();
+  friend SensorInfo ProximitySensor();
+  friend SensorInfo AmbientTempSensor();
+  friend SensorInfo DeviceTempSensor();
+  friend SensorInfo RelativeHumiditySensor();
+};
+
+SensorInfo AccelerometerSensor();
+SensorInfo GyroscopeSensor();
+SensorInfo LightSensor();
+SensorInfo MagneticFieldSensor();
+SensorInfo PressureSensor();
+SensorInfo ProximitySensor();
+SensorInfo AmbientTempSensor();
+SensorInfo DeviceTempSensor();
+SensorInfo RelativeHumiditySensor();
+
+// Stores the current state of a sensor.
+class SensorState {
+ public:
+  SensorState(SensorInfo info);
+  virtual ~SensorState() {}
+
+  // What this sensor is activated or not.
+  bool enabled_;
+  // Buffer of incoming events.
+  sensors_event_t event_;
+  // The deadline at which we should report the next sensor event
+  // to the framework in order to meet our frequency constraints.
+  // For disabled sensors, should be 'infinity'.
+  avd::time::MonotonicTimePoint deadline_;
+  // Delay time between consecutive sensor samples, in ns.
+  avd::time::Nanoseconds sampling_period_;
+
+  // Time 'infinity'.
+  static const avd::time::MonotonicTimePoint kInfinity;
+};
+
+namespace sensors_constants {
+// TODO: Verify these numbers.
+// Vendor of the hardware part.
+const char kVendor[] = "Google";
+// Version of the hardware part + driver. The value of this field
+// must increase when the driver is updated in a way that
+// changes the output of the sensor.
+const int kVersion = GCE_SENSOR_DEVICE_VERSION;
+// Number of events reserved for this sensor in batch mode FIFO.
+// If it has its own FIFO, the size of that FIFO.
+const uint32_t kFifoReservedEventCount = 15;
+// Maximum events that can be batched. In a shared FIFO,
+// the size of that FIFO.
+const uint32_t kFifoMaxEventCount = 15;
+// Permission required to use this sensor, or empty string
+// if none required.
+const char kRequiredPermission[] = "";
+// Defined only for continuous mode and on-change sensors.
+// Delay corresponding with lowest frequency supported.
+const int32_t kMaxDelay = 5000000;
+
+// Name of this sensor. Must be unique.
+const char kAccelerometerName[] = "acceleration";
+const char kGyroscopeName[] = "gyroscope";
+const char kLightName[] = "light";
+const char kMagneticFieldName[] = "magnetic_field";
+const char kPressureName[] = "pressure";
+const char kProximityName[] = "proximity";
+const char kAmbientTempName[] = "ambient_temp";
+const char kDeviceTempName[] = "device_temp";
+const char kRelativeHumidityName[] = "relative_humidity";
+
+// Handle that identifies the sensor. This is used as an array index,
+// so must be unique in the range [0, # sensors)
+
+const int kAccelerometerHandle = 0;
+const int kGyroscopeHandle = 1;
+const int kLightHandle = 2;
+const int kMagneticFieldHandle = 3;
+const int kPressureHandle = 4;
+const int kProximityHandle = 5;
+const int kAmbientTempHandle = 6;
+const int kDeviceTempHandle = 7;
+const int kRelativeHumidityHandle = 8;
+
+// For continuous sensors, minimum sample period (in microseconds).
+// On-Change (0), One-shot (-1), and special (0).
+const int32_t kAccelerometerMinDelay = 4444;
+const int32_t kGyroscopeMinDelay = 4444;
+const int32_t kLightMinDelay = 0;
+const int32_t kMagneticFieldMinDelay = 14285;
+const int32_t kPressureMinDelay = 28571;
+const int32_t kProximityMinDelay = 0;
+const int32_t kAmbientTempMinDelay = 4444;
+const int32_t kDeviceTempMinDelay = 4444;
+const int32_t kRelativeHumidityMinDelay = 4444;
+
+// Maximum range of this sensor's value in SI units.
+const float kAccelerometerMaxRange = 39.226593f;
+const float kGyroscopeMaxRange = 8.726639f;
+const float kLightMaxRange = 10000.0f;
+const float kMagneticFieldMaxRange = 4911.9995f;
+const float kPressureMaxRange = 1100.0f;
+const float kProximityMaxRange = 5.0f;
+const float kAmbientTempMaxRange = 80.0f;
+const float kDeviceTempMaxRange = 80.0f;
+const float kRelativeHumidityMaxRange = 100;
+
+// Smallest difference between two values reported by this sensor.
+const float kAccelerometerResolution = 0.45f;
+const float kGyroscopeResolution = 10.0f;
+const float kLightResolution = 10.0f;
+const float kMagneticFieldResolution = 1.0f;
+const float kPressureResolution = 1.0f;
+const float kProximityResolution = 1.0f;
+const float kAmbientTempResolution = 1.0f;
+const float kDeviceTempResolution = 1.0f;
+const float kRelativeHumidityResolution = 1.0f;
+
+// Rough estimate of this sensor's power consumption in mA.
+const float kAccelerometerPower = 0.45f;
+const float kGyroscopePower = 3.6f;
+const float kLightPower = 0.175f;
+const float kMagneticFieldPower = 5.0f;
+const float kPressurePower = 0.004f;
+const float kProximityPower = 12.675f;
+const float kAmbientTempPower = 1.0f;
+const float kDeviceTempPower = 1.0f;
+const float kRelativeHumidityPower = 1.0f;
+
+// Type of this sensor, represented as a string.
+
+#if GCE_SENSORS_DEVICE_API_VERSION_ATLEAST(1_2)
+const char kAccelerometerStringType[] = SENSOR_STRING_TYPE_ACCELEROMETER;
+const char kGyroscopeStringType[] = SENSOR_STRING_TYPE_GYROSCOPE;
+const char kLightStringType[] = SENSOR_STRING_TYPE_LIGHT;
+const char kMagneticFieldStringType[] = SENSOR_STRING_TYPE_MAGNETIC_FIELD;
+const char kPressureStringType[] = SENSOR_STRING_TYPE_PRESSURE;
+const char kProximityStringType[] = SENSOR_STRING_TYPE_PROXIMITY;
+const char kAmbientTempStringType[] = SENSOR_STRING_TYPE_AMBIENT_TEMPERATURE;
+const char kDeviceTempStringType[] = SENSOR_STRING_TYPE_TEMPERATURE;
+const char kRelativeHumidityStringType[] = SENSOR_STRING_TYPE_RELATIVE_HUMIDITY;
+#else
+const char kAccelerometerStringType[] = "";
+const char kGyroscopeStringType[] = "";
+const char kLightStringType[] = "";
+const char kMagneticFieldStringType[] = "";
+const char kPressureStringType[] = "";
+const char kProximityStringType[] = "";
+const char kAmbientTempStringType[] = "";
+const char kDeviceTempStringType[] = "";
+const char kRelativeHumidityStringType[] = "";
+#endif
+
+#if GCE_SENSORS_DEVICE_API_VERSION_ATLEAST(1_3)
+const uint32_t kAccelerometerReportingMode = SENSOR_FLAG_CONTINUOUS_MODE;
+const uint32_t kGyroscopeReportingMode = SENSOR_FLAG_CONTINUOUS_MODE;
+const uint32_t kLightReportingMode = SENSOR_FLAG_ON_CHANGE_MODE;
+const uint32_t kMagneticFieldReportingMode = SENSOR_FLAG_CONTINUOUS_MODE;
+const uint32_t kPressureReportingMode = SENSOR_FLAG_CONTINUOUS_MODE;
+const uint32_t kProximityReportingMode = SENSOR_FLAG_ON_CHANGE_MODE;
+const uint32_t kAmbientTempReportingMode = SENSOR_FLAG_ON_CHANGE_MODE;
+const uint32_t kDeviceTempReportingMode = SENSOR_FLAG_ON_CHANGE_MODE;
+const uint32_t kRelativeHumidityReportingMode = SENSOR_FLAG_ON_CHANGE_MODE;
+#else
+const uint32_t kAccelerometerReportingMode = 0;
+const uint32_t kGyroscopeReportingMode = 0;
+const uint32_t kLightReportingMode = 0;
+const uint32_t kMagneticFieldReportingMode = 0;
+const uint32_t kPressureReportingMode = 0;
+const uint32_t kProximityReportingMode = 0;
+const uint32_t kAmbientTempReportingMode = 0;
+const uint32_t kDeviceTempReportingMode = 0;
+const uint32_t kRelativeHumidityReportingMode = 0;
+#endif
+
+const bool kAccelerometerIsWakeup = false;
+const bool kGyroscopeIsWakeup = false;
+const bool kLightIsWakeup = false;
+const bool kMagneticFieldIsWakeup = false;
+const bool kPressureIsWakeup = false;
+const bool kProximityIsWakeup = true;
+const bool kAmbientTempIsWakeup = false;
+const bool kDeviceTempIsWakeup = false;
+const bool kRelativeHumidityIsWakeup = false;
+
+}  // namespace sensors_constants
+}  // namespace avd
+
+#endif
diff --git a/guest/hals/sensors/sensors_hal.cpp b/guest/hals/sensors/sensors_hal.cpp
new file mode 100644
index 0000000..e331d9f
--- /dev/null
+++ b/guest/hals/sensors/sensors_hal.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+// Google Compute Engine (GCE) Sensors HAL - Main File
+#include <api_level_fixes.h>
+
+#include "sensors_hal.h"
+#include "gce_sensors.h"
+
+static hw_module_methods_t hal_module_methods = {
+	GCE_STATIC_INITIALIZER(open) avd::GceSensors::Open,
+};
+
+sensors_module_t HAL_MODULE_INFO_SYM = {
+    GCE_STATIC_INITIALIZER(common) {
+        GCE_STATIC_INITIALIZER(tag) HARDWARE_MODULE_TAG,
+        GCE_STATIC_INITIALIZER(module_api_version) 1,
+        GCE_STATIC_INITIALIZER(hal_api_version) 0,
+        GCE_STATIC_INITIALIZER(id) SENSORS_HARDWARE_MODULE_ID,
+        GCE_STATIC_INITIALIZER(name) "Android-GCE SENSORS Module",
+        GCE_STATIC_INITIALIZER(author) "Google",
+        GCE_STATIC_INITIALIZER(methods) &hal_module_methods,
+    },
+    GCE_STATIC_INITIALIZER(get_sensors_list) avd::GceSensors::GetSensorsList,
+#if GCE_SENSORS_DEVICE_API_VERSION_ATLEAST(1_4)
+    GCE_STATIC_INITIALIZER(set_operation_mode) avd::GceSensors::SetOperationMode,
+#endif
+};
diff --git a/guest/hals/sensors/sensors_hal.h b/guest/hals/sensors/sensors_hal.h
new file mode 100644
index 0000000..c53c403
--- /dev/null
+++ b/guest/hals/sensors/sensors_hal.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+// Google Compute Engine (GCE) Sensors HAL - Main File.
+#ifndef DEVICE_GOOGLE_GCE_SENSORS_SENSORS_HAL_H
+#define DEVICE_GOOGLE_GCE_SENSORS_SENSORS_HAL_H
+
+#include <api_level_fixes.h>
+#include <cutils/log.h>
+
+#if GCE_PLATFORM_SDK_BEFORE(K)
+#define GCE_SENSOR_DEVICE_VERSION HARDWARE_MAKE_API_VERSION(0, 1)
+#elif GCE_PLATFORM_SDK_BEFORE(L)
+#define GCE_SENSOR_DEVICE_VERSION SENSORS_DEVICE_API_VERSION_1_1
+#elif GCE_PLATFORM_SDK_BEFORE(M)
+#define GCE_SENSOR_DEVICE_VERSION SENSORS_DEVICE_API_VERSION_1_3
+#else
+#define GCE_SENSOR_DEVICE_VERSION SENSORS_DEVICE_API_VERSION_1_4
+#endif
+
+#define GCE_SENSORS_DEVICE_API_VERSION_ATLEAST(X) \
+    (defined (SENSORS_DEVICE_API_VERSION_##X) && \
+     (GCE_SENSOR_DEVICE_VERSION >= SENSORS_DEVICE_API_VERSION_##X))
+
+#define SENSORS_DEBUG 0
+
+#if SENSORS_DEBUG
+#  define D(...) ALOGD(__VA_ARGS__)
+#else
+#  define D(...) ((void)0)
+#endif
+
+#include <hardware/hardware.h>
+#include <hardware/sensors.h>
+
+#endif