Merge "goldfish: update to 331578d04"
diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..fef7f95
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,22 @@
+#
+# 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+ifeq ($(BUILD_QEMU_IMAGES),true)
+  subdir_makefiles=$(call first-makefiles-under,$(LOCAL_PATH))
+  $(foreach mk,$(subdir_makefiles),$(info including $(mk) ...)$(eval include $(mk)))
+endif
diff --git a/audio/Android.mk b/audio/Android.mk
index 4343a4a..b60ff14 100644
--- a/audio/Android.mk
+++ b/audio/Android.mk
@@ -17,6 +17,7 @@
 
 include $(CLEAR_VARS)
 
+LOCAL_VENDOR_MODULE := true
 LOCAL_MODULE := audio.primary.goldfish
 LOCAL_MODULE_RELATIVE_PATH := hw
 LOCAL_MODULE_TAGS := optional
@@ -38,6 +39,7 @@
 
 include $(CLEAR_VARS)
 
+LOCAL_VENDOR_MODULE := true
 LOCAL_MODULE := audio.primary.goldfish_legacy
 LOCAL_MODULE_RELATIVE_PATH := hw
 LOCAL_MODULE_TAGS := optional
diff --git a/audio/audio_hw.c b/audio/audio_hw.c
index 2498e51..781c18f 100644
--- a/audio/audio_hw.c
+++ b/audio/audio_hw.c
@@ -16,7 +16,9 @@
 
 #define LOG_TAG "audio_hw_generic"
 
+#include <assert.h>
 #include <errno.h>
+#include <inttypes.h>
 #include <pthread.h>
 #include <stdint.h>
 #include <stdlib.h>
@@ -286,7 +288,7 @@
     pthread_mutex_lock(&out->lock);
     dprintf(fd, "\tout_dump:\n"
                 "\t\tsample rate: %u\n"
-                "\t\tbuffer size: %u\n"
+                "\t\tbuffer size: %zu\n"
                 "\t\tchannel mask: %08x\n"
                 "\t\tformat: %d\n"
                 "\t\tdevice: %08x\n"
@@ -476,7 +478,8 @@
     // The device will reuse the same output stream leading to periods of
     // underrun.
     if (*position > out->frames_written) {
-        ALOGW("Not supplying enough data to HAL, expected position %lld , only wrote %lld",
+        ALOGW("Not supplying enough data to HAL, expected position %" PRIu64 " , only wrote "
+              "%" PRIu64,
               *position, out->frames_written);
 
         *position = out->frames_written;
@@ -547,7 +550,7 @@
     }
 
     if (frames_written < frames) {
-        ALOGW("Hardware backing HAL too slow, could only write %d of %zu frames", frames_written, frames);
+        ALOGW("Hardware backing HAL too slow, could only write %zu of %zu frames", frames_written, frames);
     }
 
     /* Always consume all bytes */
@@ -795,7 +798,7 @@
     pthread_mutex_lock(&in->lock);
     dprintf(fd, "\tin_dump:\n"
                 "\t\tsample rate: %u\n"
-                "\t\tbuffer size: %u\n"
+                "\t\tbuffer size: %zu\n"
                 "\t\tchannel mask: %08x\n"
                 "\t\tformat: %d\n"
                 "\t\tdevice: %08x\n"
@@ -1027,8 +1030,9 @@
     }
 
     const int64_t frames_available = current_position - in->standby_position - in->standby_frames_read;
+    assert(frames_available >= 0);
 
-    const size_t frames_wait = (frames_available > frames) ? 0 : frames - frames_available;
+    const size_t frames_wait = ((uint64_t)frames_available > frames) ? 0 : frames - frames_available;
 
     int64_t sleep_time_us  = frames_wait * 1000000LL /
                              in_get_sample_rate(&stream->common);
diff --git a/audio/audio_hw_legacy.c b/audio/audio_hw_legacy.c
index 14d82da..5f167b5 100644
--- a/audio/audio_hw_legacy.c
+++ b/audio/audio_hw_legacy.c
@@ -106,7 +106,7 @@
 
     dprintf(fd, "\tout_dump:\n"
                 "\t\tsample rate: %u\n"
-                "\t\tbuffer size: %u\n"
+                "\t\tbuffer size: %zu\n"
                 "\t\tchannel mask: %08x\n"
                 "\t\tformat: %d\n"
                 "\t\tdevice: %08x\n"
@@ -262,7 +262,7 @@
 
     dprintf(fd, "\tin_dump:\n"
                 "\t\tsample rate: %u\n"
-                "\t\tbuffer size: %u\n"
+                "\t\tbuffer size: %zu\n"
                 "\t\tchannel mask: %08x\n"
                 "\t\tformat: %d\n"
                 "\t\tdevice: %08x\n"
diff --git a/camera/Android.mk b/camera/Android.mk
index bd33131..781e94c 100644
--- a/camera/Android.mk
+++ b/camera/Android.mk
@@ -12,6 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+ifneq ($(filter generic_x86 generic_x86_64 generic generic_arm64 generic_mips generic_mips64, $(TARGET_DEVICE)),)
 
 LOCAL_PATH := $(call my-dir)
 
@@ -32,8 +33,9 @@
     libcamera_client \
     libui \
     libdl \
-	libjpeg \
-	libcamera_metadata
+    libjpeg \
+    libcamera_metadata \
+    libhardware
 
 emulator_camera_static_libraries := \
 	libyuv_static
@@ -77,6 +79,7 @@
 
 # Emulated camera - goldfish / vbox_x86 build###################################
 
+LOCAL_VENDOR_MODULE := true
 LOCAL_MODULE_RELATIVE_PATH := ${emulator_camera_module_relative_path}
 LOCAL_CFLAGS := ${emulator_camera_cflags}
 LOCAL_CLANG_CFLAGS += ${emulator_camera_clang_flags}
@@ -100,6 +103,7 @@
 
 include ${CLEAR_VARS}
 
+LOCAL_VENDOR_MODULE := true
 LOCAL_MODULE_RELATIVE_PATH := ${emulator_camera_module_relative_path}
 LOCAL_CFLAGS := ${emulator_camera_cflags}
 LOCAL_CLANG_CFLAGS += ${emulator_camera_clang_flags}
@@ -116,3 +120,4 @@
 # Build all subdirectories #####################################################
 include $(call all-makefiles-under,$(LOCAL_PATH))
 
+endif
diff --git a/camera/CallbackNotifier.cpp b/camera/CallbackNotifier.cpp
index 18c5eec..865a34e 100755
--- a/camera/CallbackNotifier.cpp
+++ b/camera/CallbackNotifier.cpp
@@ -239,7 +239,7 @@
         // format it expects and the preview callback (or data callback) below
         // gets the format that is configured in camera parameters.
         const size_t frameSize = camera_dev->getVideoFrameBufferSize();
-        camera_memory_t* cam_buff = mGetMemoryCB(-1, frameSize, 1, NULL);
+        camera_memory_t* cam_buff = mGetMemoryCB(-1, frameSize, 1, mCBOpaque);
         if (NULL != cam_buff && NULL != cam_buff->data) {
             camera_dev->getCurrentFrame(cam_buff->data, V4L2_PIX_FMT_YUV420);
             mDataCBTimestamp(timestamp, CAMERA_MSG_VIDEO_FRAME,
@@ -252,7 +252,7 @@
 
     if (isMessageEnabled(CAMERA_MSG_PREVIEW_FRAME)) {
         camera_memory_t* cam_buff =
-            mGetMemoryCB(-1, camera_dev->getFrameBufferSize(), 1, NULL);
+            mGetMemoryCB(-1, camera_dev->getFrameBufferSize(), 1, mCBOpaque);
         if (NULL != cam_buff && NULL != cam_buff->data) {
             camera_dev->getCurrentFrame(cam_buff->data,
                                         camera_dev->getOriginalPixelFormat());
@@ -313,7 +313,7 @@
                                                        mJpegQuality, exifData);
             if (res == NO_ERROR) {
                 camera_memory_t* jpeg_buff =
-                    mGetMemoryCB(-1, compressor.getCompressedSize(), 1, NULL);
+                    mGetMemoryCB(-1, compressor.getCompressedSize(), 1, mCBOpaque);
                 if (NULL != jpeg_buff && NULL != jpeg_buff->data) {
                     compressor.getCompressedImage(jpeg_buff->data);
                     mDataCB(CAMERA_MSG_COMPRESSED_IMAGE, jpeg_buff, 0, NULL, mCBOpaque);
diff --git a/camera/EmulatedCamera.cpp b/camera/EmulatedCamera.cpp
index bdab833..66cadee 100755
--- a/camera/EmulatedCamera.cpp
+++ b/camera/EmulatedCamera.cpp
@@ -26,7 +26,7 @@
 #define LOG_NDEBUG 0
 #define LOG_TAG "EmulatedCamera_Camera"
 #include <cutils/log.h>
-#include <ui/Rect.h>
+ #include <stdio.h>
 #include "EmulatedCamera.h"
 //#include "EmulatedFakeCameraDevice.h"
 #include "Converters.h"
@@ -386,12 +386,17 @@
 status_t EmulatedCamera::storeMetaDataInBuffers(int enable)
 {
     /* Callback should return a negative errno. */
-    return -mCallbackNotifier.storeMetaDataInBuffers(enable);
+    return mCallbackNotifier.storeMetaDataInBuffers(enable);
 }
 
 status_t EmulatedCamera::startRecording()
 {
     /* This callback should return a negative errno, hence all the negations */
+    if (!mPreviewWindow.isPreviewEnabled()) {
+        ALOGE("%s: start recording without preview enabled",
+              __FUNCTION__);
+        return INVALID_OPERATION;
+    }
     int frameRate = mParameters.getPreviewFrameRate();
     status_t res = mCallbackNotifier.enableVideoRecording(frameRate);
     if (res != NO_ERROR) {
@@ -439,6 +444,7 @@
             return -EINVAL;
         }
     }
+    ALOGD("go all the way to the end");
     return NO_ERROR;
 }
 
@@ -766,7 +772,8 @@
     ALOGV("%s", __FUNCTION__);
 
     /* TODO: Future enhancements. */
-    return -EINVAL;
+    dprintf(fd, "dump camera unimplemented\n");
+    return 0;
 }
 
 status_t EmulatedCamera::getConfiguredPixelFormat(uint32_t* pixelFormat) const {
diff --git a/camera/EmulatedCameraFactory.h b/camera/EmulatedCameraFactory.h
index 879f925..923fe7e 100755
--- a/camera/EmulatedCameraFactory.h
+++ b/camera/EmulatedCameraFactory.h
@@ -121,13 +121,13 @@
     /* Gets fake camera orientation. */
     int getFakeCameraOrientation() {
         /* TODO: Have a boot property that controls that. */
-        return 90;
+        return 0;
     }
 
     /* Gets qemu camera orientation. */
     int getQemuCameraOrientation() {
         /* TODO: Have a boot property that controls that. */
-        return 90;
+        return 0;
     }
 
     /* Gets number of emulated cameras.
diff --git a/camera/EmulatedFakeCamera.cpp b/camera/EmulatedFakeCamera.cpp
index 3db1a80..c85285d 100755
--- a/camera/EmulatedFakeCamera.cpp
+++ b/camera/EmulatedFakeCamera.cpp
@@ -60,6 +60,8 @@
 
     mParameters.set(EmulatedCamera::ORIENTATION_KEY,
                     gEmulatedCameraFactory.getFakeCameraOrientation());
+    mParameters.set(CameraParameters::KEY_ROTATION,
+                    gEmulatedCameraFactory.getFakeCameraOrientation());
 
     res = EmulatedCamera::Initialize();
     if (res != NO_ERROR) {
diff --git a/camera/EmulatedFakeCamera2.cpp b/camera/EmulatedFakeCamera2.cpp
index 7df6f52..9e959c0 100644
--- a/camera/EmulatedFakeCamera2.cpp
+++ b/camera/EmulatedFakeCamera2.cpp
@@ -27,9 +27,7 @@
 
 #include "EmulatedFakeCamera2.h"
 #include "EmulatedCameraFactory.h"
-#include <ui/Rect.h>
-#include <ui/GraphicBufferMapper.h>
-#include "gralloc_cb.h"
+#include "GrallocModule.h"
 
 #define ERROR_CAMERA_NOT_PRESENT (-EPIPE)
 
@@ -51,7 +49,7 @@
 
 const uint32_t EmulatedFakeCamera2::kAvailableRawSizes[2] = {
     640, 480
-    //    Sensor::kResolution[0], Sensor::kResolution[1]
+    //    mSensorWidth, mSensorHeight
 };
 
 const uint64_t EmulatedFakeCamera2::kAvailableRawMinDurations[1] = {
@@ -60,12 +58,12 @@
 
 const uint32_t EmulatedFakeCamera2::kAvailableProcessedSizesBack[4] = {
     640, 480, 320, 240
-    //    Sensor::kResolution[0], Sensor::kResolution[1]
+    //    mSensorWidth, mSensorHeight
 };
 
 const uint32_t EmulatedFakeCamera2::kAvailableProcessedSizesFront[4] = {
     320, 240, 160, 120
-    //    Sensor::kResolution[0], Sensor::kResolution[1]
+    //    mSensorWidth, mSensorHeight
 };
 
 const uint64_t EmulatedFakeCamera2::kAvailableProcessedMinDurations[1] = {
@@ -74,12 +72,12 @@
 
 const uint32_t EmulatedFakeCamera2::kAvailableJpegSizesBack[2] = {
     640, 480
-    //    Sensor::kResolution[0], Sensor::kResolution[1]
+    //    mSensorWidth, mSensorHeight
 };
 
 const uint32_t EmulatedFakeCamera2::kAvailableJpegSizesFront[2] = {
     320, 240
-    //    Sensor::kResolution[0], Sensor::kResolution[1]
+    //    mSensorWidth, mSensorHeight
 };
 
 
@@ -112,6 +110,24 @@
 status_t EmulatedFakeCamera2::Initialize() {
     status_t res;
 
+    // Find max width/height
+    int32_t width = 0, height = 0;
+    size_t rawSizeCount = sizeof(kAvailableRawSizes)/sizeof(kAvailableRawSizes[0]);
+    for (size_t index = 0; index + 1 < rawSizeCount; index += 2) {
+        if (width <= kAvailableRawSizes[index] &&
+            height <= kAvailableRawSizes[index+1]) {
+            width = kAvailableRawSizes[index];
+            height = kAvailableRawSizes[index+1];
+        }
+    }
+
+    if (width < 640 || height < 480) {
+        width = 640;
+        height = 480;
+    }
+    mSensorWidth = width;
+    mSensorHeight = height;
+
     res = constructStaticInfo(&mCameraInfo, true);
     if (res != OK) {
         ALOGE("%s: Unable to allocate static info: %s (%d)",
@@ -156,7 +172,7 @@
     mConfigureThread = new ConfigureThread(this);
     mReadoutThread = new ReadoutThread(this);
     mControlThread = new ControlThread(this);
-    mSensor = new Sensor();
+    mSensor = new Sensor(mSensorWidth, mSensorHeight);
     mJpegCompressor = new JpegCompressor();
 
     mNextStreamId = 1;
@@ -479,17 +495,6 @@
                 __FUNCTION__, stream_id, num_buffers);
         return BAD_VALUE;
     }
-    const cb_handle_t *streamBuffer =
-            reinterpret_cast<const cb_handle_t*>(buffers[0]);
-
-    int finalFormat = streamBuffer->format;
-
-    if (finalFormat == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
-        ALOGE("%s: Stream %d: Bad final pixel format "
-                "HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; "
-                "concrete pixel format required!", __FUNCTION__, stream_id);
-        return BAD_VALUE;
-    }
 
     ssize_t streamIndex = mStreams.indexOfKey(stream_id);
     if (streamIndex < 0) {
@@ -499,6 +504,12 @@
 
     Stream &stream = mStreams.editValueAt(streamIndex);
 
+    int finalFormat = stream.format;
+
+    if (finalFormat == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
+        finalFormat = HAL_PIXEL_FORMAT_RGBA_8888;
+    }
+
     ALOGV("%s: Stream %d format set to %x, previously %x",
             __FUNCTION__, stream_id, finalFormat, stream.format);
 
@@ -1058,11 +1069,11 @@
             }
 
             /* Lock the buffer from the perspective of the graphics mapper */
-            const Rect rect(s.width, s.height);
-
-            res = GraphicBufferMapper::get().lock(*(b.buffer),
+            res = GrallocModule::getInstance().lock(*(b.buffer),
                     GRALLOC_USAGE_HW_CAMERA_WRITE,
-                    rect, (void**)&(b.img) );
+                    0, 0, s.width, s.height,
+                    (void**)&(b.img));
+
 
             if (res != NO_ERROR) {
                 ALOGE("%s: grbuffer_mapper.lock failure: %s (%d)",
@@ -1086,11 +1097,10 @@
             }
 
             /* Lock the buffer from the perspective of the graphics mapper */
-            const Rect rect(s.width, s.height);
-
-            res = GraphicBufferMapper::get().lock(*(b.buffer),
+            res = GrallocModule::getInstance().lock(*(b.buffer),
                     GRALLOC_USAGE_HW_CAMERA_READ,
-                    rect, (void**)&(b.img) );
+                    0, 0, s.width, s.height,
+                    (void**)&(b.img) );
             if (res != NO_ERROR) {
                 ALOGE("%s: grbuffer_mapper.lock failure: %s (%d)",
                         __FUNCTION__, strerror(-res), res);
@@ -1366,7 +1376,7 @@
             } else {
                 ALOGV("Readout:    Sending image buffer %zu (%p) to output stream %d",
                         i, (void*)*(b.buffer), b.streamId);
-                GraphicBufferMapper::get().unlock(*(b.buffer));
+                GrallocModule::getInstance().unlock(*(b.buffer));
                 const Stream &s = mParent->getStreamInfo(b.streamId);
                 res = s.ops->enqueue_buffer(s.ops, captureTime, b.buffer);
                 if (res != OK) {
@@ -1410,7 +1420,7 @@
     ALOGV("%s: Compression complete, pushing to stream %d", __FUNCTION__,
             jpegBuffer.streamId);
 
-    GraphicBufferMapper::get().unlock(*(jpegBuffer.buffer));
+    GrallocModule::getInstance().unlock(*(jpegBuffer.buffer));
     const Stream &s = mParent->getStreamInfo(jpegBuffer.streamId);
     res = s.ops->enqueue_buffer(s.ops, mJpegTimestamp, jpegBuffer.buffer);
 }
@@ -1418,7 +1428,7 @@
 void EmulatedFakeCamera2::ReadoutThread::onJpegInputDone(
         const StreamBuffer &inputBuffer) {
     status_t res;
-    GraphicBufferMapper::get().unlock(*(inputBuffer.buffer));
+    GrallocModule::getInstance().unlock(*(inputBuffer.buffer));
     const ReprocessStream &s =
             mParent->getReprocessStreamInfo(-inputBuffer.streamId);
     res = s.ops->release_buffer(s.ops, inputBuffer.buffer);
@@ -1455,15 +1465,15 @@
     // the rectangles don't line up quite right.
     const size_t numFaces = 2;
     int32_t rects[numFaces * 4] = {
-        static_cast<int32_t>(Sensor::kResolution[0] * 10 / 20),
-        static_cast<int32_t>(Sensor::kResolution[1] * 15 / 20),
-        static_cast<int32_t>(Sensor::kResolution[0] * 12 / 20),
-        static_cast<int32_t>(Sensor::kResolution[1] * 17 / 20),
+        static_cast<int32_t>(mParent->mSensorWidth * 10 / 20),
+        static_cast<int32_t>(mParent->mSensorHeight * 15 / 20),
+        static_cast<int32_t>(mParent->mSensorWidth * 12 / 20),
+        static_cast<int32_t>(mParent->mSensorHeight * 17 / 20),
 
-        static_cast<int32_t>(Sensor::kResolution[0] * 16 / 20),
-        static_cast<int32_t>(Sensor::kResolution[1] * 15 / 20),
-        static_cast<int32_t>(Sensor::kResolution[0] * 18 / 20),
-        static_cast<int32_t>(Sensor::kResolution[1] * 17 / 20)
+        static_cast<int32_t>(mParent->mSensorWidth * 16 / 20),
+        static_cast<int32_t>(mParent->mSensorHeight * 15 / 20),
+        static_cast<int32_t>(mParent->mSensorWidth * 18 / 20),
+        static_cast<int32_t>(mParent->mSensorHeight * 17 / 20)
     };
     // To simulate some kind of real detection going on, we jitter the rectangles on
     // each frame by a few pixels in each dimension.
@@ -1496,19 +1506,19 @@
     // coordinates in order are (leftEyeX, leftEyeY, rightEyeX, rightEyeY,
     // mouthX, mouthY). The mapping is the same as the face rectangles.
     int32_t features[numFaces * 6] = {
-        static_cast<int32_t>(Sensor::kResolution[0] * 10.5 / 20),
-        static_cast<int32_t>(Sensor::kResolution[1] * 16 / 20),
-        static_cast<int32_t>(Sensor::kResolution[0] * 11.5 / 20),
-        static_cast<int32_t>(Sensor::kResolution[1] * 16 / 20),
-        static_cast<int32_t>(Sensor::kResolution[0] * 11 / 20),
-        static_cast<int32_t>(Sensor::kResolution[1] * 16.5 / 20),
+        static_cast<int32_t>(mParent->mSensorWidth * 10.5 / 20),
+        static_cast<int32_t>(mParent->mSensorHeight * 16 / 20),
+        static_cast<int32_t>(mParent->mSensorWidth * 11.5 / 20),
+        static_cast<int32_t>(mParent->mSensorHeight * 16 / 20),
+        static_cast<int32_t>(mParent->mSensorWidth * 11 / 20),
+        static_cast<int32_t>(mParent->mSensorHeight * 16.5 / 20),
 
-        static_cast<int32_t>(Sensor::kResolution[0] * 16.5 / 20),
-        static_cast<int32_t>(Sensor::kResolution[1] * 16 / 20),
-        static_cast<int32_t>(Sensor::kResolution[0] * 17.5 / 20),
-        static_cast<int32_t>(Sensor::kResolution[1] * 16 / 20),
-        static_cast<int32_t>(Sensor::kResolution[0] * 17 / 20),
-        static_cast<int32_t>(Sensor::kResolution[1] * 16.5 / 20),
+        static_cast<int32_t>(mParent->mSensorWidth * 16.5 / 20),
+        static_cast<int32_t>(mParent->mSensorHeight * 16 / 20),
+        static_cast<int32_t>(mParent->mSensorWidth * 17.5 / 20),
+        static_cast<int32_t>(mParent->mSensorHeight * 16 / 20),
+        static_cast<int32_t>(mParent->mSensorWidth * 17 / 20),
+        static_cast<int32_t>(mParent->mSensorHeight * 16.5 / 20),
     };
     // Jitter these a bit less than the rects
     for (size_t i = 0; i < numFaces * 6; i++) {
@@ -2124,11 +2134,12 @@
     ADD_OR_SIZE(ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
             sensorPhysicalSize, 2);
 
+    const int32_t pixelArray[] = {mSensorWidth, mSensorHeight};
     ADD_OR_SIZE(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
-            Sensor::kResolution, 2);
+            pixelArray, 2);
 
     ADD_OR_SIZE(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
-            Sensor::kResolution, 2);
+            pixelArray, 2);
 
     ADD_OR_SIZE(ANDROID_SENSOR_INFO_WHITE_LEVEL,
             &Sensor::kMaxRawValue, 1);
@@ -2498,7 +2509,7 @@
 
     /** android.scaler */
     static const int32_t cropRegion[3] = {
-        0, 0, static_cast<int32_t>(Sensor::kResolution[0])
+        0, 0, static_cast<int32_t>(mSensorWidth)
     };
     ADD_OR_SIZE(ANDROID_SCALER_CROP_REGION, cropRegion, 3);
 
@@ -2586,8 +2597,8 @@
 
     static const int32_t controlRegions[5] = {
         0, 0,
-        static_cast<int32_t>(Sensor::kResolution[0]),
-        static_cast<int32_t>(Sensor::kResolution[1]),
+        static_cast<int32_t>(mSensorWidth),
+        static_cast<int32_t>(mSensorHeight),
         1000
     };
     ADD_OR_SIZE(ANDROID_CONTROL_AE_REGIONS, controlRegions, 5);
diff --git a/camera/EmulatedFakeCamera2.h b/camera/EmulatedFakeCamera2.h
index 64c8667..b695016 100644
--- a/camera/EmulatedFakeCamera2.h
+++ b/camera/EmulatedFakeCamera2.h
@@ -402,6 +402,8 @@
 private:
     bool mIsConnected;
 
+    int32_t mSensorWidth, mSensorHeight;
+
     /** Stream manipulation */
     uint32_t mNextStreamId;
     uint32_t mRawStreamCount;
diff --git a/camera/EmulatedFakeCamera3.cpp b/camera/EmulatedFakeCamera3.cpp
index 0e305f9..6aa3c5b 100644
--- a/camera/EmulatedFakeCamera3.cpp
+++ b/camera/EmulatedFakeCamera3.cpp
@@ -30,9 +30,7 @@
 #include "EmulatedFakeCamera3.h"
 #include "EmulatedCameraFactory.h"
 #include <ui/Fence.h>
-#include <ui/Rect.h>
-#include <ui/GraphicBufferMapper.h>
-#include "gralloc_cb.h"
+#include "GrallocModule.h"
 
 #include "fake-pipeline2/Sensor.h"
 #include "fake-pipeline2/JpegCompressor.h"
@@ -68,6 +66,12 @@
         HAL_PIXEL_FORMAT_Y16
 };
 
+const uint32_t EmulatedFakeCamera3::kAvailableRawSizes[2] = {
+    640, 480
+    //    mSensorWidth, mSensorHeight
+};
+
+
 /**
  * 3A constants
  */
@@ -77,7 +81,8 @@
 const nsecs_t EmulatedFakeCamera3::kFacePriorityExposureTime = 30 * MSEC;
 const int     EmulatedFakeCamera3::kNormalSensitivity        = 100;
 const int     EmulatedFakeCamera3::kFacePrioritySensitivity  = 400;
-const float   EmulatedFakeCamera3::kExposureTrackRate        = 0.1;
+//CTS requires 8 frames timeout in waitForAeStable
+const float   EmulatedFakeCamera3::kExposureTrackRate        = 0.2;
 const int     EmulatedFakeCamera3::kPrecaptureMinFrames      = 10;
 const int     EmulatedFakeCamera3::kStableAeMaxFrames        = 100;
 const float   EmulatedFakeCamera3::kExposureWanderMin        = -2;
@@ -97,7 +102,6 @@
     for (size_t i = 0; i < CAMERA3_TEMPLATE_COUNT; i++) {
         mDefaultTemplates[i] = NULL;
     }
-
 }
 
 EmulatedFakeCamera3::~EmulatedFakeCamera3() {
@@ -144,7 +148,7 @@
         return INVALID_OPERATION;
     }
 
-    mSensor = new Sensor();
+    mSensor = new Sensor(mSensorWidth, mSensorHeight);
     mSensor->setSensorListener(this);
 
     res = mSensor->startUp();
@@ -536,7 +540,7 @@
     /** android.scaler */
     if (hasCapability(BACKWARD_COMPATIBLE)) {
         static const int32_t cropRegion[4] = {
-            0, 0, (int32_t)Sensor::kResolution[0], (int32_t)Sensor::kResolution[1]
+            0, 0, mSensorWidth, mSensorHeight
         };
         settings.update(ANDROID_SCALER_CROP_REGION, cropRegion, 4);
     }
@@ -666,28 +670,33 @@
         settings.update(ANDROID_CONTROL_AWB_LOCK, &awbLock, 1);
 
         uint8_t afMode = 0;
-        switch (type) {
-            case CAMERA3_TEMPLATE_PREVIEW:
-                afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE;
-                break;
-            case CAMERA3_TEMPLATE_STILL_CAPTURE:
-                afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE;
-                break;
-            case CAMERA3_TEMPLATE_VIDEO_RECORD:
-                afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO;
-                break;
-            case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
-                afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO;
-                break;
-            case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
-                afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE;
-                break;
-            case CAMERA3_TEMPLATE_MANUAL:
-                afMode = ANDROID_CONTROL_AF_MODE_OFF;
-                break;
-            default:
-                afMode = ANDROID_CONTROL_AF_MODE_AUTO;
-                break;
+
+        if (mFacingBack) {
+            switch (type) {
+                case CAMERA3_TEMPLATE_PREVIEW:
+                    afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE;
+                    break;
+                case CAMERA3_TEMPLATE_STILL_CAPTURE:
+                    afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE;
+                    break;
+                case CAMERA3_TEMPLATE_VIDEO_RECORD:
+                    afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO;
+                    break;
+                case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
+                    afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO;
+                    break;
+                case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
+                    afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE;
+                    break;
+                case CAMERA3_TEMPLATE_MANUAL:
+                    afMode = ANDROID_CONTROL_AF_MODE_OFF;
+                    break;
+                default:
+                    afMode = ANDROID_CONTROL_AF_MODE_AUTO;
+                    break;
+            }
+        } else {
+            afMode = ANDROID_CONTROL_AF_MODE_OFF;
         }
         settings.update(ANDROID_CONTROL_AF_MODE, &afMode, 1);
 
@@ -863,18 +872,15 @@
     // structures for them, and lock them for writing.
     for (size_t i = 0; i < request->num_output_buffers; i++) {
         const camera3_stream_buffer &srcBuf = request->output_buffers[i];
-        const cb_handle_t *privBuffer =
-                static_cast<const cb_handle_t*>(*srcBuf.buffer);
-        if (!cb_handle_t::validate(privBuffer)) {
-          privBuffer = nullptr;
-        }
         StreamBuffer destBuf;
         destBuf.streamId = kGenericStreamId;
         destBuf.width    = srcBuf.stream->width;
         destBuf.height   = srcBuf.stream->height;
-        // If we have more specific format information, use it.
-        destBuf.format = (privBuffer) ? privBuffer->format : srcBuf.stream->format;
-        destBuf.stride   = srcBuf.stream->width; // TODO: query from gralloc
+        // For goldfish, IMPLEMENTATION_DEFINED is always RGBx_8888
+        destBuf.format = (srcBuf.stream->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) ?
+                HAL_PIXEL_FORMAT_RGBA_8888 :
+                srcBuf.stream->format;
+        destBuf.stride   = srcBuf.stream->width;
         destBuf.dataSpace = srcBuf.stream->data_space;
         destBuf.buffer   = srcBuf.buffer;
 
@@ -891,13 +897,13 @@
         }
         if (res == OK) {
             // Lock buffer for writing
-            const Rect rect(destBuf.width, destBuf.height);
             if (srcBuf.stream->format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
-                if (destBuf.format == HAL_PIXEL_FORMAT_YCrCb_420_SP) {
+                if (destBuf.format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
                     android_ycbcr ycbcr = android_ycbcr();
-                    res = GraphicBufferMapper::get().lockYCbCr(
+                    res = GrallocModule::getInstance().lock_ycbcr(
                         *(destBuf.buffer),
-                        GRALLOC_USAGE_HW_CAMERA_WRITE, rect,
+                        GRALLOC_USAGE_HW_CAMERA_WRITE,
+                        0, 0, destBuf.width, destBuf.height,
                         &ycbcr);
                     // This is only valid because we know that emulator's
                     // YCbCr_420_888 is really contiguous NV21 under the hood
@@ -908,9 +914,12 @@
                     res = INVALID_OPERATION;
                 }
             } else {
-                res = GraphicBufferMapper::get().lock(*(destBuf.buffer),
-                        GRALLOC_USAGE_HW_CAMERA_WRITE, rect,
-                        (void**)&(destBuf.img));
+                res = GrallocModule::getInstance().lock(
+                    *(destBuf.buffer),
+                    GRALLOC_USAGE_HW_CAMERA_WRITE,
+                    0, 0, destBuf.width, destBuf.height,
+                    (void**)&(destBuf.img));
+
             }
             if (res != OK) {
                 ALOGE("%s: Request %d: Buffer %zu: Unable to lock buffer",
@@ -922,7 +931,7 @@
             // Either waiting or locking failed. Unlock locked buffers and bail
             // out.
             for (size_t j = 0; j < i; j++) {
-                GraphicBufferMapper::get().unlock(
+                GrallocModule::getInstance().unlock(
                         *(request->output_buffers[i].buffer));
             }
             delete sensorBuffers;
@@ -938,12 +947,17 @@
      * Wait for JPEG compressor to not be busy, if needed
      */
     if (needJpeg) {
-        bool ready = mJpegCompressor->waitForDone(kFenceTimeoutMs);
+        bool ready = mJpegCompressor->waitForDone(kJpegTimeoutNs);
         if (!ready) {
             ALOGE("%s: Timeout waiting for JPEG compression to complete!",
                     __FUNCTION__);
             return NO_INIT;
         }
+        res = mJpegCompressor->reserve();
+        if (res != OK) {
+            ALOGE("%s: Error managing JPEG compressor resources, can't reserve it!", __FUNCTION__);
+            return NO_INIT;
+        }
     }
 
     /**
@@ -1083,6 +1097,24 @@
     Vector<int32_t> availableCharacteristicsKeys;
     status_t res;
 
+    // Find max width/height
+    int32_t width = 0, height = 0;
+    size_t rawSizeCount = sizeof(kAvailableRawSizes)/sizeof(kAvailableRawSizes[0]);
+    for (size_t index = 0; index + 1 < rawSizeCount; index += 2) {
+        if (width <= kAvailableRawSizes[index] &&
+            height <= kAvailableRawSizes[index+1]) {
+            width = kAvailableRawSizes[index];
+            height = kAvailableRawSizes[index+1];
+        }
+    }
+
+    if (width < 640 || height < 480) {
+        width = 640;
+        height = 480;
+    }
+    mSensorWidth = width;
+    mSensorHeight = height;
+
 #define ADD_STATIC_ENTRY(name, varptr, count) \
         availableCharacteristicsKeys.add(name);   \
         res = info.update(name, varptr, count); \
@@ -1111,11 +1143,12 @@
     ADD_STATIC_ENTRY(ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
             sensorPhysicalSize, 2);
 
+    const int32_t pixelArray[] = {mSensorWidth, mSensorHeight};
     ADD_STATIC_ENTRY(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
-            (int32_t*)Sensor::kResolution, 2);
-
+            pixelArray, 2);
+    const int32_t activeArray[] = {0, 0, mSensorWidth, mSensorHeight};
     ADD_STATIC_ENTRY(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
-            (int32_t*)Sensor::kActiveArray, 4);
+            activeArray, 4);
 
     static const int32_t orientation = 90; // Aligned with 'long edge'
     ADD_STATIC_ENTRY(ANDROID_SENSOR_ORIENTATION, &orientation, 1);
@@ -1210,10 +1243,10 @@
                 sizeof(lensPoseTranslation)/sizeof(float));
 
         // Intrinsics are 'ideal' (f_x, f_y, c_x, c_y, s) match focal length and active array size
-        float f_x = focalLength * Sensor::kActiveArray[2] / sensorPhysicalSize[0];
-        float f_y = focalLength * Sensor::kActiveArray[3] / sensorPhysicalSize[1];
-        float c_x = Sensor::kActiveArray[2] / 2.f;
-        float c_y = Sensor::kActiveArray[3] / 2.f;
+        float f_x = focalLength * mSensorWidth / sensorPhysicalSize[0];
+        float f_y = focalLength * mSensorHeight / sensorPhysicalSize[1];
+        float c_x = mSensorWidth / 2.f;
+        float c_y = mSensorHeight / 2.f;
         float s = 0.f;
         const float lensIntrinsics[] = { f_x, f_y, c_x, c_y, s };
 
@@ -1256,18 +1289,27 @@
     // android.scaler
 
     const std::vector<int32_t> availableStreamConfigurationsBasic = {
+        HAL_PIXEL_FORMAT_BLOB, width, height, ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
         HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, 320, 240, ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
         HAL_PIXEL_FORMAT_YCbCr_420_888, 320, 240, ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
-        HAL_PIXEL_FORMAT_RGBA_8888, 320, 240, ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
-        HAL_PIXEL_FORMAT_BLOB, 640, 480, ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT
+        HAL_PIXEL_FORMAT_BLOB, 320, 240, ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
     };
-    const std::vector<int32_t> availableStreamConfigurationsRaw = {
-        HAL_PIXEL_FORMAT_RAW16, 640, 480, ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT
-    };
-    const std::vector<int32_t> availableStreamConfigurationsBurst = {
+
+    // Always need to include 640x480 in basic formats
+    const std::vector<int32_t> availableStreamConfigurationsBasic640 = {
         HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, 640, 480, ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
         HAL_PIXEL_FORMAT_YCbCr_420_888, 640, 480, ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
-        HAL_PIXEL_FORMAT_RGBA_8888, 640, 480, ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT
+        HAL_PIXEL_FORMAT_BLOB, 640, 480, ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT
+    };
+
+    const std::vector<int32_t> availableStreamConfigurationsRaw = {
+        HAL_PIXEL_FORMAT_RAW16, width, height, ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
+    };
+
+    const std::vector<int32_t> availableStreamConfigurationsBurst = {
+        HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, width, height, ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
+        HAL_PIXEL_FORMAT_YCbCr_420_888, width, height, ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
+        HAL_PIXEL_FORMAT_RGBA_8888, width, height, ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
     };
 
     std::vector<int32_t> availableStreamConfigurations;
@@ -1276,6 +1318,11 @@
         availableStreamConfigurations.insert(availableStreamConfigurations.end(),
                 availableStreamConfigurationsBasic.begin(),
                 availableStreamConfigurationsBasic.end());
+        if (width > 640) {
+            availableStreamConfigurations.insert(availableStreamConfigurations.end(),
+                    availableStreamConfigurationsBasic640.begin(),
+                    availableStreamConfigurationsBasic640.end());
+        }
     }
     if (hasCapability(RAW)) {
         availableStreamConfigurations.insert(availableStreamConfigurations.end(),
@@ -1295,18 +1342,27 @@
     }
 
     const std::vector<int64_t> availableMinFrameDurationsBasic = {
+        HAL_PIXEL_FORMAT_BLOB, width, height, Sensor::kFrameDurationRange[0],
         HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, 320, 240, Sensor::kFrameDurationRange[0],
         HAL_PIXEL_FORMAT_YCbCr_420_888, 320, 240, Sensor::kFrameDurationRange[0],
-        HAL_PIXEL_FORMAT_RGBA_8888, 320, 240, Sensor::kFrameDurationRange[0],
-        HAL_PIXEL_FORMAT_BLOB, 640, 480, Sensor::kFrameDurationRange[0]
+        HAL_PIXEL_FORMAT_BLOB, 320, 240, Sensor::kFrameDurationRange[0],
     };
-    const std::vector<int64_t> availableMinFrameDurationsRaw = {
-        HAL_PIXEL_FORMAT_RAW16, 640, 480, Sensor::kFrameDurationRange[0]
-    };
-    const std::vector<int64_t> availableMinFrameDurationsBurst = {
+
+    // Always need to include 640x480 in basic formats
+    const std::vector<int64_t> availableMinFrameDurationsBasic640 = {
         HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, 640, 480, Sensor::kFrameDurationRange[0],
         HAL_PIXEL_FORMAT_YCbCr_420_888, 640, 480, Sensor::kFrameDurationRange[0],
-        HAL_PIXEL_FORMAT_RGBA_8888, 640, 480, Sensor::kFrameDurationRange[0],
+        HAL_PIXEL_FORMAT_BLOB, 640, 480, Sensor::kFrameDurationRange[0]
+    };
+
+    const std::vector<int64_t> availableMinFrameDurationsRaw = {
+        HAL_PIXEL_FORMAT_RAW16, width, height, Sensor::kFrameDurationRange[0],
+    };
+
+    const std::vector<int64_t> availableMinFrameDurationsBurst = {
+        HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, width, height, Sensor::kFrameDurationRange[0],
+        HAL_PIXEL_FORMAT_YCbCr_420_888, width, height, Sensor::kFrameDurationRange[0],
+        HAL_PIXEL_FORMAT_RGBA_8888, width, height, Sensor::kFrameDurationRange[0],
     };
 
     std::vector<int64_t> availableMinFrameDurations;
@@ -1315,6 +1371,11 @@
         availableMinFrameDurations.insert(availableMinFrameDurations.end(),
                 availableMinFrameDurationsBasic.begin(),
                 availableMinFrameDurationsBasic.end());
+        if (width > 640) {
+            availableMinFrameDurations.insert(availableMinFrameDurations.end(),
+                    availableMinFrameDurationsBasic640.begin(),
+                    availableMinFrameDurationsBasic640.end());
+        }
     }
     if (hasCapability(RAW)) {
         availableMinFrameDurations.insert(availableMinFrameDurations.end(),
@@ -1334,11 +1395,19 @@
     }
 
     const std::vector<int64_t> availableStallDurationsBasic = {
+        HAL_PIXEL_FORMAT_BLOB, width, height, Sensor::kFrameDurationRange[0],
         HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, 320, 240, 0,
         HAL_PIXEL_FORMAT_YCbCr_420_888, 320, 240, 0,
         HAL_PIXEL_FORMAT_RGBA_8888, 320, 240, 0,
+    };
+
+    // Always need to include 640x480 in basic formats
+    const std::vector<int64_t> availableStallDurationsBasic640 = {
+        HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, 640, 480, 0,
+        HAL_PIXEL_FORMAT_YCbCr_420_888, 640, 480, 0,
         HAL_PIXEL_FORMAT_BLOB, 640, 480, Sensor::kFrameDurationRange[0]
     };
+
     const std::vector<int64_t> availableStallDurationsRaw = {
         HAL_PIXEL_FORMAT_RAW16, 640, 480, Sensor::kFrameDurationRange[0]
     };
@@ -1354,6 +1423,11 @@
         availableStallDurations.insert(availableStallDurations.end(),
                 availableStallDurationsBasic.begin(),
                 availableStallDurationsBasic.end());
+        if (width > 640) {
+            availableStallDurations.insert(availableStallDurations.end(),
+                    availableStallDurationsBasic640.begin(),
+                    availableStallDurationsBasic640.end());
+        }
     }
     if (hasCapability(RAW)) {
         availableStallDurations.insert(availableStallDurations.end(),
@@ -1786,6 +1860,9 @@
     uint8_t controlMode = e.data.u8[0];
 
     if (controlMode == ANDROID_CONTROL_MODE_OFF) {
+        mAeMode   = ANDROID_CONTROL_AE_MODE_OFF;
+        mAfMode   = ANDROID_CONTROL_AF_MODE_OFF;
+        mAwbMode  = ANDROID_CONTROL_AWB_MODE_OFF;
         mAeState  = ANDROID_CONTROL_AE_STATE_INACTIVE;
         mAfState  = ANDROID_CONTROL_AF_STATE_INACTIVE;
         mAwbState = ANDROID_CONTROL_AWB_STATE_INACTIVE;
@@ -1843,6 +1920,7 @@
         return BAD_VALUE;
     }
     uint8_t aeMode = (e.count > 0) ? e.data.u8[0] : (uint8_t)ANDROID_CONTROL_AE_MODE_ON;
+    mAeMode = aeMode;
 
     switch (aeMode) {
         case ANDROID_CONTROL_AE_MODE_OFF:
@@ -1908,8 +1986,10 @@
     } else if (!aeLocked) {
         // Run standard occasional AE scan
         switch (mAeState) {
-            case ANDROID_CONTROL_AE_STATE_CONVERGED:
             case ANDROID_CONTROL_AE_STATE_INACTIVE:
+                mAeState = ANDROID_CONTROL_AE_STATE_SEARCHING;
+                break;
+            case ANDROID_CONTROL_AE_STATE_CONVERGED:
                 mAeCounter++;
                 if (mAeCounter > kStableAeMaxFrames) {
                     mAeTargetExposureTime =
@@ -2171,16 +2251,21 @@
 
     // TODO: Add white balance simulation
 
+    e = settings.find(ANDROID_CONTROL_AWB_LOCK);
+    bool awbLocked = (e.count > 0) ? (e.data.u8[0] == ANDROID_CONTROL_AWB_LOCK_ON) : false;
+
     switch (awbMode) {
         case ANDROID_CONTROL_AWB_MODE_OFF:
             mAwbState = ANDROID_CONTROL_AWB_STATE_INACTIVE;
-            return OK;
+            break;
         case ANDROID_CONTROL_AWB_MODE_AUTO:
         case ANDROID_CONTROL_AWB_MODE_INCANDESCENT:
         case ANDROID_CONTROL_AWB_MODE_FLUORESCENT:
         case ANDROID_CONTROL_AWB_MODE_DAYLIGHT:
         case ANDROID_CONTROL_AWB_MODE_SHADE:
-            // OK
+            // Always magically right, or locked
+            mAwbState = awbLocked ? ANDROID_CONTROL_AWB_STATE_LOCKED :
+                    ANDROID_CONTROL_AWB_STATE_CONVERGED;
             break;
         default:
             ALOGE("%s: Emulator doesn't support AWB mode %d",
@@ -2387,7 +2472,7 @@
                         __FUNCTION__, strerror(-res), res);
             // fallthrough for cleanup
         }
-        GraphicBufferMapper::get().unlock(*(buf->buffer));
+        GrallocModule::getInstance().unlock(*(buf->buffer));
 
         buf->status = goodBuffer ? CAMERA3_BUFFER_STATUS_OK :
                 CAMERA3_BUFFER_STATUS_ERROR;
@@ -2489,7 +2574,7 @@
         const StreamBuffer &jpegBuffer, bool success) {
     Mutex::Autolock jl(mJpegLock);
 
-    GraphicBufferMapper::get().unlock(*(jpegBuffer.buffer));
+    GrallocModule::getInstance().unlock(*(jpegBuffer.buffer));
 
     mJpegHalBuffer.status = success ?
             CAMERA3_BUFFER_STATUS_OK : CAMERA3_BUFFER_STATUS_ERROR;
@@ -2498,10 +2583,13 @@
     mJpegWaiting = false;
 
     camera3_capture_result result;
+
     result.frame_number = mJpegFrameNumber;
     result.result = NULL;
     result.num_output_buffers = 1;
     result.output_buffers = &mJpegHalBuffer;
+    result.input_buffer = nullptr;
+    result.partial_result = 0;
 
     if (!success) {
         ALOGE("%s: Compression failure, returning error state buffer to"
diff --git a/camera/EmulatedFakeCamera3.h b/camera/EmulatedFakeCamera3.h
index 4835009..3921178 100644
--- a/camera/EmulatedFakeCamera3.h
+++ b/camera/EmulatedFakeCamera3.h
@@ -139,10 +139,11 @@
     // no concept of a stream id.
     static const uint32_t kGenericStreamId = 1;
     static const int32_t  kAvailableFormats[];
-
+    static const uint32_t kAvailableRawSizes[];
     static const int64_t  kSyncWaitTimeout     = 10000000; // 10 ms
     static const int32_t  kMaxSyncTimeoutCount = 1000; // 1000 kSyncWaitTimeouts
     static const uint32_t kFenceTimeoutMs      = 2000; // 2 s
+    static const nsecs_t  kJpegTimeoutNs       = 5000000000l; // 5 s
 
     /****************************************************************************
      * Data members.
@@ -153,6 +154,8 @@
 
     /* Facing back (true) or front (false) switch. */
     bool               mFacingBack;
+    int32_t            mSensorWidth;
+    int32_t            mSensorHeight;
 
     SortedVector<AvailableCapabilities> mCapabilities;
 
diff --git a/camera/EmulatedQemuCamera.cpp b/camera/EmulatedQemuCamera.cpp
index ce47f07..eb2c4be 100755
--- a/camera/EmulatedQemuCamera.cpp
+++ b/camera/EmulatedQemuCamera.cpp
@@ -138,6 +138,8 @@
     mParameters.set(EmulatedCamera::FACING_KEY, facing_dir);
     mParameters.set(EmulatedCamera::ORIENTATION_KEY,
                     gEmulatedCameraFactory.getQemuCameraOrientation());
+    mParameters.set(CameraParameters::KEY_ROTATION,
+                    gEmulatedCameraFactory.getQemuCameraOrientation());
     mParameters.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
                     sizes.c_str());
     mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
diff --git a/camera/Exif.cpp b/camera/Exif.cpp
index aa58f4b..d444824 100644
--- a/camera/Exif.cpp
+++ b/camera/Exif.cpp
@@ -280,11 +280,16 @@
     float triplet[3];
     float floatValue = 0.0f;
     const char* stringValue;
+    int64_t degrees;
 
     // Datetime, creating and initializing a datetime tag will automatically
     // set the current date and time in the tag so just do that.
     createEntry(exifData, EXIF_IFD_0, EXIF_TAG_DATE_TIME);
 
+    // Make and model
+    createEntry(exifData, EXIF_IFD_0, EXIF_TAG_MAKE, "Emulator-Goldfish");
+    createEntry(exifData, EXIF_IFD_0, EXIF_TAG_MODEL, "Emulator-Goldfish");
+
     // Picture size
     int width = -1, height = -1;
     params.getPictureSize(&width, &height);
@@ -294,6 +299,38 @@
         createEntry(exifData, EXIF_IFD_EXIF,
                     EXIF_TAG_PIXEL_Y_DIMENSION, height);
     }
+    // Orientation
+    if (getCameraParam(params,
+                       CameraParameters::KEY_ROTATION,
+                       &degrees)) {
+        // Exif orientation values, please refer to
+        // http://www.exif.org/Exif2-2.PDF, Section 4.6.4-A-Orientation
+        // Or these websites:
+        // http://sylvana.net/jpegcrop/exif_orientation.html
+        // http://www.impulseadventure.com/photo/exif-orientation.html
+        enum {
+            EXIF_ROTATE_CAMERA_CW0 = 1,
+            EXIF_ROTATE_CAMERA_CW90 = 6,
+            EXIF_ROTATE_CAMERA_CW180 = 3,
+            EXIF_ROTATE_CAMERA_CW270 = 8,
+        };
+        uint16_t exifOrien = 1;
+        switch (degrees) {
+            case 0:
+                exifOrien = EXIF_ROTATE_CAMERA_CW0;
+                break;
+            case 90:
+                exifOrien = EXIF_ROTATE_CAMERA_CW90;
+                break;
+            case 180:
+                exifOrien = EXIF_ROTATE_CAMERA_CW180;
+                break;
+            case 270:
+                exifOrien = EXIF_ROTATE_CAMERA_CW270;
+                break;
+        }
+        createEntry(exifData, EXIF_IFD_0, EXIF_TAG_ORIENTATION, exifOrien);
+    }
     // Focal length
     if (getCameraParam(params,
                        CameraParameters::KEY_FOCAL_LENGTH,
diff --git a/camera/GrallocModule.h b/camera/GrallocModule.h
new file mode 100644
index 0000000..1f5a8f2
--- /dev/null
+++ b/camera/GrallocModule.h
@@ -0,0 +1,43 @@
+#ifndef EMU_CAMERA_GRALLOC_MODULE_H
+#define EMU_CAMERA_GRALLOC_MODULE_H
+
+#include <hardware/gralloc.h>
+
+class GrallocModule
+{
+public:
+  static GrallocModule &getInstance() {
+    static GrallocModule instance;
+    return instance;
+  }
+
+  int lock(buffer_handle_t handle,
+      int usage, int l, int t, int w, int h, void **vaddr) {
+    return mModule->lock(mModule, handle, usage, l, t, w, h, vaddr);
+  }
+
+#ifdef GRALLOC_MODULE_API_VERSION_0_2
+  int lock_ycbcr(buffer_handle_t handle,
+      int usage, int l, int t, int w, int h,
+      struct android_ycbcr *ycbcr) {
+    return mModule->lock_ycbcr(mModule, handle, usage, l, t, w, h, ycbcr);
+  }
+#endif
+
+  int unlock(buffer_handle_t handle) {
+    return mModule->unlock(mModule, handle);
+  }
+
+private:
+  GrallocModule() {
+    const hw_module_t *module = NULL;
+    int ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
+    if (ret) {
+      ALOGE("%s: Failed to get gralloc module: %d", __FUNCTION__, ret);
+    }
+    mModule = reinterpret_cast<const gralloc_module_t*>(module);
+  }
+  const gralloc_module_t *mModule;
+};
+
+#endif
diff --git a/camera/JpegCompressor.cpp b/camera/JpegCompressor.cpp
index 9694ca3..d757a3d 100644
--- a/camera/JpegCompressor.cpp
+++ b/camera/JpegCompressor.cpp
@@ -46,7 +46,7 @@
 
 NV21JpegCompressor::NV21JpegCompressor()
 {
-    const char dlName[] = "/system/lib/hw/camera.goldfish.jpeg.so";
+    const char dlName[] = "/vendor/lib/hw/camera.goldfish.jpeg.so";
     if (mDl == NULL) {
         mDl = dlopen(dlName, RTLD_NOW);
     }
diff --git a/camera/PreviewWindow.cpp b/camera/PreviewWindow.cpp
index 68d3d5d..607ad7d 100755
--- a/camera/PreviewWindow.cpp
+++ b/camera/PreviewWindow.cpp
@@ -22,10 +22,9 @@
 #define LOG_NDEBUG 0
 #define LOG_TAG "EmulatedCamera_Preview"
 #include <cutils/log.h>
-#include <ui/Rect.h>
-#include <ui/GraphicBufferMapper.h>
 #include "EmulatedCameraDevice.h"
 #include "PreviewWindow.h"
+#include "GrallocModule.h"
 
 namespace android {
 
@@ -150,11 +149,11 @@
     /* Now let the graphics framework to lock the buffer, and provide
      * us with the framebuffer data address. */
     void* img = NULL;
-    const Rect rect(mPreviewFrameWidth, mPreviewFrameHeight);
-    GraphicBufferMapper& grbuffer_mapper(GraphicBufferMapper::get());
-    res = grbuffer_mapper.lock(*buffer, GRALLOC_USAGE_SW_WRITE_OFTEN, rect, &img);
+    res = GrallocModule::getInstance().lock(
+        *buffer, GRALLOC_USAGE_SW_WRITE_OFTEN,
+        0, 0, mPreviewFrameWidth, mPreviewFrameHeight, &img);
     if (res != NO_ERROR) {
-        ALOGE("%s: grbuffer_mapper.lock failure: %d -> %s",
+        ALOGE("%s: gralloc.lock failure: %d -> %s",
              __FUNCTION__, res, strerror(res));
         mPreviewWindow->cancel_buffer(mPreviewWindow, buffer);
         return;
@@ -171,7 +170,7 @@
         ALOGE("%s: Unable to obtain preview frame: %d", __FUNCTION__, res);
         mPreviewWindow->cancel_buffer(mPreviewWindow, buffer);
     }
-    grbuffer_mapper.unlock(*buffer);
+    GrallocModule::getInstance().unlock(*buffer);
 }
 
 /***************************************************************************
diff --git a/camera/fake-pipeline2/Base.h b/camera/fake-pipeline2/Base.h
index 724b3f9..473a9f3 100644
--- a/camera/fake-pipeline2/Base.h
+++ b/camera/fake-pipeline2/Base.h
@@ -22,7 +22,6 @@
 #ifndef HW_EMULATOR_CAMERA2_BASE_H
 #define HW_EMULATOR_CAMERA2_BASE_H
 
-#include <system/window.h>
 #include <hardware/camera2.h>
 #include <utils/Vector.h>
 
diff --git a/camera/fake-pipeline2/JpegCompressor.cpp b/camera/fake-pipeline2/JpegCompressor.cpp
index d0dce26..5dad236 100644
--- a/camera/fake-pipeline2/JpegCompressor.cpp
+++ b/camera/fake-pipeline2/JpegCompressor.cpp
@@ -18,7 +18,6 @@
 #define LOG_TAG "EmulatedCamera2_JpegCompressor"
 
 #include <utils/Log.h>
-#include <ui/GraphicBufferMapper.h>
 
 #include "JpegCompressor.h"
 #include "../EmulatedFakeCamera2.h"
@@ -38,6 +37,16 @@
     Mutex::Autolock lock(mMutex);
 }
 
+status_t JpegCompressor::reserve() {
+    Mutex::Autolock busyLock(mBusyMutex);
+    if (mIsBusy) {
+        ALOGE("%s: Already processing a buffer!", __FUNCTION__);
+        return INVALID_OPERATION;
+    }
+    mIsBusy = true;
+    return OK;
+}
+
 status_t JpegCompressor::start(Buffers *buffers, JpegListener *listener) {
     if (listener == NULL) {
         ALOGE("%s: NULL listener not allowed!", __FUNCTION__);
@@ -47,12 +56,10 @@
     {
         Mutex::Autolock busyLock(mBusyMutex);
 
-        if (mIsBusy) {
-            ALOGE("%s: Already processing a buffer!", __FUNCTION__);
+        if (!mIsBusy) {
+            ALOGE("Called start without reserve() first!");
             return INVALID_OPERATION;
         }
-
-        mIsBusy = true;
         mSynchronous = false;
         mBuffers = buffers;
         mListener = listener;
@@ -117,7 +124,6 @@
 status_t JpegCompressor::compress() {
     // Find source and target buffers. Assumes only one buffer matches
     // each condition!
-
     bool foundJpeg = false, mFoundAux = false;
     for (size_t i = 0; i < mBuffers->size(); i++) {
         const StreamBuffer &b = (*mBuffers)[i];
@@ -215,11 +221,11 @@
 
 bool JpegCompressor::waitForDone(nsecs_t timeout) {
     Mutex::Autolock lock(mBusyMutex);
-    status_t res = OK;
-    if (mIsBusy) {
-        res = mDone.waitRelative(mBusyMutex, timeout);
+    while (mIsBusy) {
+        status_t res = mDone.waitRelative(mBusyMutex, timeout);
+        if (res != OK) return false;
     }
-    return (res == OK);
+    return true;
 }
 
 bool JpegCompressor::checkError(const char *msg) {
diff --git a/camera/fake-pipeline2/JpegCompressor.h b/camera/fake-pipeline2/JpegCompressor.h
index ff6f8a4..597cbdf 100644
--- a/camera/fake-pipeline2/JpegCompressor.h
+++ b/camera/fake-pipeline2/JpegCompressor.h
@@ -56,6 +56,7 @@
 
     // Start compressing COMPRESSED format buffers; JpegCompressor takes
     // ownership of the Buffers vector.
+    // Reserve() must be called first.
     status_t start(Buffers *buffers, JpegListener *listener);
 
     // Compress and block until buffer is complete.
@@ -68,6 +69,9 @@
 
     bool waitForDone(nsecs_t timeout);
 
+    // Reserve the compressor for a later start() call.
+    status_t reserve();
+
     // TODO: Measure this
     static const size_t kMaxJpegSize = 300000;
 
diff --git a/camera/fake-pipeline2/Sensor.cpp b/camera/fake-pipeline2/Sensor.cpp
index 61c7f28..02c6835 100644
--- a/camera/fake-pipeline2/Sensor.cpp
+++ b/camera/fake-pipeline2/Sensor.cpp
@@ -34,9 +34,6 @@
 
 namespace android {
 
-const unsigned int Sensor::kResolution[2]  = {640, 480};
-const unsigned int Sensor::kActiveArray[4]  = {0, 0, 640, 480};
-
 //const nsecs_t Sensor::kExposureTimeRange[2] =
 //    {1000L, 30000000000L} ; // 1 us - 30 sec
 //const nsecs_t Sensor::kFrameDurationRange[2] =
@@ -76,13 +73,6 @@
             Sensor::kReadNoiseStddevAfterGain *
             Sensor::kReadNoiseStddevAfterGain;
 
-// While each row has to read out, reset, and then expose, the (reset +
-// expose) sequence can be overlapped by other row readouts, so the final
-// minimum frame duration is purely a function of row readout time, at least
-// if there's a reasonable number of rows.
-const nsecs_t Sensor::kRowReadoutTime =
-            Sensor::kFrameDurationRange[0] / Sensor::kResolution[1];
-
 const int32_t Sensor::kSensitivityRange[2] = {100, 1600};
 const uint32_t Sensor::kDefaultSensitivity = 100;
 
@@ -105,8 +95,11 @@
 
 
 
-Sensor::Sensor():
+Sensor::Sensor(uint32_t width, uint32_t height):
         Thread(false),
+        mResolution{width, height},
+        mActiveArray{0, 0, width, height},
+        mRowReadoutTime(kFrameDurationRange[0] / height),
         mGotVSync(false),
         mExposureTime(kFrameDurationRange[0]-kMinVerticalBlank),
         mFrameDuration(kFrameDurationRange[0]),
@@ -115,9 +108,9 @@
         mFrameNumber(0),
         mCapturedBuffers(NULL),
         mListener(NULL),
-        mScene(kResolution[0], kResolution[1], kElectronsPerLuxSecond)
+        mScene(width, height, kElectronsPerLuxSecond)
 {
-
+    ALOGV("Sensor created with pixel array %d x %d", width, height);
 }
 
 Sensor::~Sensor() {
@@ -207,9 +200,8 @@
             ALOGE("Error waiting for sensor readout signal: %d", res);
             return false;
         }
-    } else {
-        mReadoutComplete.signal();
     }
+    mReadoutComplete.signal();
 
     *captureTime = mCaptureTime;
     mCapturedBuffers = NULL;
@@ -279,7 +271,7 @@
     nsecs_t simulatedTime    = startRealTime;
     nsecs_t frameEndRealTime = startRealTime + frameDuration;
     nsecs_t frameReadoutEndRealTime = startRealTime +
-            kRowReadoutTime * kResolution[1];
+            mRowReadoutTime * mResolution[1];
 
     if (mNextCapturedBuffers != NULL) {
         ALOGVV("Sensor starting readout");
@@ -287,7 +279,7 @@
         capturedBuffers = mNextCapturedBuffers;
         captureTime    = mNextCaptureTime;
     }
-    simulatedTime += kRowReadoutTime + kMinVerticalBlank;
+    simulatedTime += mRowReadoutTime + kMinVerticalBlank;
 
     // TODO: Move this signal to another thread to simulate readout
     // time properly
@@ -357,7 +349,7 @@
                         captureDepthCloud(b.img);
                     }
                     break;
-                case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+                case HAL_PIXEL_FORMAT_YCbCr_420_888:
                     captureNV21(b.img, gain, b.stride);
                     break;
                 case HAL_PIXEL_FORMAT_YV12:
@@ -403,10 +395,10 @@
 
     int bayerSelect[4] = {Scene::R, Scene::Gr, Scene::Gb, Scene::B}; // RGGB
     mScene.setReadoutPixel(0,0);
-    for (unsigned int y = 0; y < kResolution[1]; y++ ) {
+    for (unsigned int y = 0; y < mResolution[1]; y++ ) {
         int *bayerRow = bayerSelect + (y & 0x1) * 2;
         uint16_t *px = (uint16_t*)img + y * stride;
-        for (unsigned int x = 0; x < kResolution[0]; x++) {
+        for (unsigned int x = 0; x < mResolution[0]; x++) {
             uint32_t electronCount;
             electronCount = mScene.getPixelElectrons()[bayerRow[x & 0x1]];
 
@@ -431,7 +423,7 @@
             *px++ = rawCount;
         }
         // TODO: Handle this better
-        //simulatedTime += kRowReadoutTime;
+        //simulatedTime += mRowReadoutTime;
     }
     ALOGVV("Raw sensor image captured");
 }
@@ -440,12 +432,12 @@
     float totalGain = gain/100.0 * kBaseGainFactor;
     // In fixed-point math, calculate total scaling from electrons to 8bpp
     int scale64x = 64 * totalGain * 255 / kMaxRawValue;
-    uint32_t inc = kResolution[0] / stride;
+    uint32_t inc = ceil( (float) mResolution[0] / stride);
 
-    for (unsigned int y = 0, outY = 0; y < kResolution[1]; y+=inc, outY++ ) {
+    for (unsigned int y = 0, outY = 0; y < mResolution[1]; y+=inc, outY++ ) {
         uint8_t *px = img + outY * stride * 4;
         mScene.setReadoutPixel(0, y);
-        for (unsigned int x = 0; x < kResolution[0]; x+=inc) {
+        for (unsigned int x = 0; x < mResolution[0]; x+=inc) {
             uint32_t rCount, gCount, bCount;
             // TODO: Perfect demosaicing is a cheat
             const uint32_t *pixel = mScene.getPixelElectrons();
@@ -461,7 +453,7 @@
                 mScene.getPixelElectrons();
         }
         // TODO: Handle this better
-        //simulatedTime += kRowReadoutTime;
+        //simulatedTime += mRowReadoutTime;
     }
     ALOGVV("RGBA sensor image captured");
 }
@@ -470,12 +462,12 @@
     float totalGain = gain/100.0 * kBaseGainFactor;
     // In fixed-point math, calculate total scaling from electrons to 8bpp
     int scale64x = 64 * totalGain * 255 / kMaxRawValue;
-    uint32_t inc = kResolution[0] / stride;
+    uint32_t inc = ceil( (float) mResolution[0] / stride);
 
-    for (unsigned int y = 0, outY = 0; y < kResolution[1]; y += inc, outY++ ) {
+    for (unsigned int y = 0, outY = 0; y < mResolution[1]; y += inc, outY++ ) {
         mScene.setReadoutPixel(0, y);
         uint8_t *px = img + outY * stride * 3;
-        for (unsigned int x = 0; x < kResolution[0]; x += inc) {
+        for (unsigned int x = 0; x < mResolution[0]; x += inc) {
             uint32_t rCount, gCount, bCount;
             // TODO: Perfect demosaicing is a cheat
             const uint32_t *pixel = mScene.getPixelElectrons();
@@ -490,7 +482,7 @@
                 mScene.getPixelElectrons();
         }
         // TODO: Handle this better
-        //simulatedTime += kRowReadoutTime;
+        //simulatedTime += mRowReadoutTime;
     }
     ALOGVV("RGB sensor image captured");
 }
@@ -512,10 +504,13 @@
     const int scaleOut = 64;
     const int scaleOutSq = scaleOut * scaleOut; // after multiplies
 
-    uint32_t inc = kResolution[0] / stride;
-    uint32_t outH = kResolution[1] / inc;
+    // inc = how many pixels to skip while reading every next pixel
+    // horizontally.
+    uint32_t inc = ceil( (float) mResolution[0] / stride);
+    // outH = projected vertical resolution based on stride.
+    uint32_t outH = mResolution[1] / inc;
     for (unsigned int y = 0, outY = 0;
-         y < kResolution[1]; y+=inc, outY++) {
+         y < mResolution[1]; y+=inc, outY++) {
         uint8_t *pxY = img + outY * stride;
         uint8_t *pxVU = img + (outH + outY / 2) * stride;
         mScene.setReadoutPixel(0,y);
@@ -554,12 +549,12 @@
     float totalGain = gain/100.0 * kBaseGainFactor;
     // In fixed-point math, calculate scaling factor to 13bpp millimeters
     int scale64x = 64 * totalGain * 8191 / kMaxRawValue;
-    uint32_t inc = kResolution[0] / stride;
+    uint32_t inc = ceil( (float) mResolution[0] / stride);
 
-    for (unsigned int y = 0, outY = 0; y < kResolution[1]; y += inc, outY++ ) {
+    for (unsigned int y = 0, outY = 0; y < mResolution[1]; y += inc, outY++ ) {
         mScene.setReadoutPixel(0, y);
         uint16_t *px = ((uint16_t*)img) + outY * stride;
-        for (unsigned int x = 0; x < kResolution[0]; x += inc) {
+        for (unsigned int x = 0; x < mResolution[0]; x += inc) {
             uint32_t depthCount;
             // TODO: Make up real depth scene instead of using green channel
             // as depth
@@ -571,7 +566,7 @@
                 mScene.getPixelElectrons();
         }
         // TODO: Handle this better
-        //simulatedTime += kRowReadoutTime;
+        //simulatedTime += mRowReadoutTime;
     }
     ALOGVV("Depth sensor image captured");
 }
diff --git a/camera/fake-pipeline2/Sensor.h b/camera/fake-pipeline2/Sensor.h
index 720fbc2..cdf1e97 100644
--- a/camera/fake-pipeline2/Sensor.h
+++ b/camera/fake-pipeline2/Sensor.h
@@ -89,7 +89,9 @@
 class Sensor: private Thread, public virtual RefBase {
   public:
 
-    Sensor();
+    // width: Width of pixel array
+    // height: Height of pixel array
+    Sensor(uint32_t width, uint32_t height);
     ~Sensor();
 
     /*
@@ -157,8 +159,8 @@
     /**
      * Static sensor characteristics
      */
-    static const unsigned int kResolution[2];
-    static const unsigned int kActiveArray[4];
+    const uint32_t mResolution[2];
+    const uint32_t mActiveArray[4];
 
     static const nsecs_t kExposureTimeRange[2];
     static const nsecs_t kFrameDurationRange[2];
@@ -187,7 +189,7 @@
     // expose) sequence can be overlapped by other row readouts, so the final
     // minimum frame duration is purely a function of row readout time, at least
     // if there's a reasonable number of rows.
-    static const nsecs_t kRowReadoutTime;
+    const nsecs_t mRowReadoutTime;
 
     static const int32_t kSensitivityRange[2];
     static const uint32_t kDefaultSensitivity;
diff --git a/camera/jpeg-stub/Android.mk b/camera/jpeg-stub/Android.mk
index eea0ced..e017ac1 100644
--- a/camera/jpeg-stub/Android.mk
+++ b/camera/jpeg-stub/Android.mk
@@ -22,6 +22,7 @@
 ifneq ($(TARGET_BUILD_PDK),true)
 
 include $(CLEAR_VARS)
+LOCAL_VENDOR_MODULE := true
 
 jpeg_module_relative_path := hw
 jpeg_cflags := -fno-short-enums -DQEMU_HARDWARE
@@ -59,6 +60,7 @@
 
 include ${CLEAR_VARS}
 
+LOCAL_VENDOR_MODULE := true
 LOCAL_MODULE := camera.ranchu.jpeg
 
 LOCAL_MODULE_RELATIVE_PATH := ${jpeg_module_relative_path}
diff --git a/camera/media_codecs_performance.xml b/camera/media_codecs_performance.xml
index 3d12ceb..b82e4c8 100644
--- a/camera/media_codecs_performance.xml
+++ b/camera/media_codecs_performance.xml
@@ -100,10 +100,10 @@
             <Limit name="measured-frame-rate-320x180" range="968-1101" />
             <!-- 3 runs, min 291 max 338 gmean 319 -->
             <Limit name="measured-frame-rate-640x360" range="291-338" />
-            <!-- 3 runs, min 109 max 128 gmean 118 -->
-            <Limit name="measured-frame-rate-1280x720" range="109-128" />
-            <!-- 5 runs, min 69 max 76 gmean 73 -->
-            <Limit name="measured-frame-rate-1920x1080" range="69-76" />
+            <!-- Those values are from buildbots -->
+            <Limit name="measured-frame-rate-1280x720" range="280-400" />
+            <!-- Buildbot gets ~180 if it is in the first run, ~230 if it is the second run -->
+            <Limit name="measured-frame-rate-1920x1080" range="178-240" />
         </MediaCodec>
     </Decoders>
 </MediaCodecs>
diff --git a/compatibility_matrix.xml b/compatibility_matrix.xml
new file mode 100644
index 0000000..3082485
--- /dev/null
+++ b/compatibility_matrix.xml
@@ -0,0 +1,59 @@
+<compatibility-matrix version="1.0" type="device">
+    <hal format="hidl" optional="false">
+        <name>android.frameworks.schedulerservice</name>
+        <version>1.0</version>
+        <interface>
+            <name>ISchedulingPolicyService</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="false">
+        <name>android.frameworks.sensorservice</name>
+        <version>1.0</version>
+        <interface>
+            <name>ISensorManager</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="false">
+        <name>android.hidl.allocator</name>
+        <version>1.0</version>
+        <interface>
+            <name>IAllocator</name>
+            <instance>ashmem</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="false">
+        <name>android.hidl.manager</name>
+        <version>1.0</version>
+        <interface>
+            <name>IServiceManager</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="false">
+        <name>android.hidl.memory</name>
+        <version>1.0</version>
+        <interface>
+            <name>IMapper</name>
+            <instance>ashmem</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="false">
+        <name>android.hidl.token</name>
+        <version>1.0</version>
+        <interface>
+            <name>ITokenManager</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="false">
+        <name>android.system.wifi.keystore</name>
+        <version>1.0</version>
+        <interface>
+            <name>IKeystore</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+
+</compatibility-matrix>
diff --git a/data/etc/config.ini b/data/etc/config.ini
new file mode 100644
index 0000000..c78b6b8
--- /dev/null
+++ b/data/etc/config.ini
@@ -0,0 +1,20 @@
+avd.ini.encoding=UTF-8
+disk.dataPartition.size=2G
+hw.accelerometer=yes
+hw.audioInput=yes
+hw.battery=yes
+hw.camera.back=emulated
+hw.camera.front=none
+hw.dPad=no
+hw.gps=yes
+hw.gpu.enabled=yes
+hw.keyboard=yes
+hw.lcd.density=240
+hw.mainKeys=no
+hw.ramSize=2048
+hw.sensors.orientation=yes
+hw.sensors.proximity=yes
+image.sysdir.1=x86/
+skin.dynamic=no
+skin.name=480x800
+skin.path=480x800
diff --git a/data/etc/handheld_core_hardware.xml b/data/etc/handheld_core_hardware.xml
index b2aaf13..728e5ba 100644
--- a/data/etc/handheld_core_hardware.xml
+++ b/data/etc/handheld_core_hardware.xml
@@ -32,6 +32,7 @@
              android.hardware.sensor.light
              android.hardware.sensor.proximity
              android.hardware.sensor.relative_humidity
+             android.hardware.sensor.gyroscope
              android.hardware.telephony
              android.hardware.telephony.gsm
              android.software.midi
@@ -49,6 +50,7 @@
     <feature name="android.hardware.sensor.light" />
     <feature name="android.hardware.sensor.proximity" />
     <feature name="android.hardware.sensor.relative_humidity" />
+    <feature name="android.hardware.sensor.gyroscope" />
     <feature name="android.hardware.telephony" />
     <feature name="android.hardware.telephony.gsm" />
     <feature name="android.hardware.touchscreen" />
diff --git a/fingerprint/Android.mk b/fingerprint/Android.mk
index be21c97..55e513c 100644
--- a/fingerprint/Android.mk
+++ b/fingerprint/Android.mk
@@ -16,6 +16,7 @@
 
 include $(CLEAR_VARS)
 
+LOCAL_VENDOR_MODULE := true
 LOCAL_MODULE := fingerprint.goldfish
 LOCAL_MODULE_RELATIVE_PATH := hw
 LOCAL_C_INCLUDES += $(LOCAL_PATH)/../include
@@ -26,6 +27,7 @@
 
 include $(CLEAR_VARS)
 
+LOCAL_VENDOR_MODULE := true
 LOCAL_MODULE := fingerprint.ranchu
 LOCAL_MODULE_RELATIVE_PATH := hw
 LOCAL_C_INCLUDES += $(LOCAL_PATH)/../include
diff --git a/fingerprint/fingerprint.c b/fingerprint/fingerprint.c
index 6041005..dd37770 100644
--- a/fingerprint/fingerprint.c
+++ b/fingerprint/fingerprint.c
@@ -308,11 +308,15 @@
         const hw_auth_token_t *hat,
         uint32_t __unused gid,
         uint32_t __unused timeout_sec) {
+    fingerprint_msg_t msg = {0, {0}};
+    msg.type = FINGERPRINT_ERROR;
+    msg.data.error = FINGERPRINT_ERROR_UNABLE_TO_PROCESS;
     ALOGD("fingerprint_enroll");
     qemu_fingerprint_device_t* dev = (qemu_fingerprint_device_t*)device;
     if (!hat) {
         ALOGW("%s: null auth token", __func__);
-        return -EPROTONOSUPPORT;
+        dev->device.notify(&msg);
+        return 0;
     }
     if (hat->challenge == dev->challenge) {
         // The secure_user_id retrieved from the auth token should be stored
@@ -324,10 +328,12 @@
     }
 
     if (hat->version != HW_AUTH_TOKEN_VERSION) {
-        return -EPROTONOSUPPORT;
+        dev->device.notify(&msg);
+        return 0;
     }
     if (hat->challenge != dev->challenge && !(hat->authenticator_type & HW_AUTH_FINGERPRINT)) {
-        return -EPERM;
+        dev->device.notify(&msg);
+        return 0;
     }
 
     dev->user_id = hat->user_id;
@@ -447,7 +453,7 @@
         ALOGE("Can't remove fingerprint (gid=%d, fid=%d); "
               "device not initialized properly",
               gid, fid);
-        return -1;
+        return -ENODEV;
     }
 
     qemu_fingerprint_device_t* qdev = (qemu_fingerprint_device_t*)device;
@@ -472,6 +478,7 @@
                     pthread_mutex_unlock(&qdev->lock);
                     msg.type = FINGERPRINT_TEMPLATE_REMOVED;
                     msg.data.removed.finger.fid = theFid;
+                    msg.data.removed.finger.gid = qdev->group_id;
                     device->notify(&msg);
 
                     // Because we released the mutex, the list
@@ -486,6 +493,7 @@
         pthread_mutex_unlock(&qdev->lock);
         msg.type = FINGERPRINT_TEMPLATE_REMOVED;
         msg.data.removed.finger.fid = 0;
+        msg.data.removed.finger.gid = qdev->group_id;
         device->notify(&msg);
     } else {
         // Delete one fingerprint
@@ -502,7 +510,15 @@
             qdev->listener.state = STATE_IDLE;
             pthread_mutex_unlock(&qdev->lock);
             ALOGE("Fingerprint ID %d not found", fid);
-            return FINGERPRINT_ERROR;
+            //msg.type = FINGERPRINT_ERROR;
+            //msg.data.error = FINGERPRINT_ERROR_UNABLE_TO_REMOVE;
+            //device->notify(&msg);
+            msg.type = FINGERPRINT_TEMPLATE_REMOVED;
+            msg.data.removed.finger.fid = 0;
+            msg.data.removed.finger.gid = qdev->group_id;
+            msg.data.removed.remaining_templates = 0;
+            device->notify(&msg);
+            return 0;
         }
 
         qdev->listener.secureid[idx] = 0;
diff --git a/fstab.ranchu b/fstab.ranchu
index a4a0817..e5040bd 100644
--- a/fstab.ranchu
+++ b/fstab.ranchu
@@ -4,4 +4,4 @@
 # specify MF_CHECK, and must come before any filesystems that do specify MF_CHECK
 /dev/block/vdb                                          /cache              ext4      noatime,nosuid,nodev,nomblk_io_submit,errors=panic   wait
 /dev/block/vdc                                          /data               ext4      noatime,nosuid,nodev,nomblk_io_submit,errors=panic   wait,check,quota,forceencrypt=/dev/block/vdd
-/devices/*/block/vde                                    auto                auto      defaults                                             voldmanaged=sdcard:auto,encryptable=userdata
+/devices/*/block/vdf                                    auto                auto      defaults                                             voldmanaged=sdcard:auto,encryptable=userdata
diff --git a/fstab.ranchu.arm b/fstab.ranchu.arm
new file mode 100644
index 0000000..6197823
--- /dev/null
+++ b/fstab.ranchu.arm
@@ -0,0 +1,7 @@
+# Android fstab file.
+#<src>                                                  <mnt_point>         <type>    <mnt_flags and options>                              <fs_mgr_flags>
+# The filesystem that contains the filesystem checker binary (typically /system) cannot
+# specify MF_CHECK, and must come before any filesystems that do specify MF_CHECK
+/dev/block/vdb                                          /cache              ext4      noatime,nosuid,nodev,nomblk_io_submit,errors=panic   wait
+/dev/block/vdc                                          /data               ext4      noatime,nosuid,nodev,nomblk_io_submit,errors=panic   wait,check,quota
+/devices/*/block/vde                                    auto                auto      defaults                                             voldmanaged=sdcard:auto,encryptable=userdata
diff --git a/fstab.ranchu.early b/fstab.ranchu.early
new file mode 100644
index 0000000..915d923
--- /dev/null
+++ b/fstab.ranchu.early
@@ -0,0 +1,6 @@
+# Android fstab file.
+#<src>                                                  <mnt_point>         <type>    <mnt_flags and options>                              <fs_mgr_flags>
+# The filesystem that contains the filesystem checker binary (typically /system) cannot
+# specify MF_CHECK, and must come before any filesystems that do specify MF_CHECK
+/dev/block/vda                                          /system             ext4      ro                                                   wait
+/dev/block/vde                                          /vendor             ext4      ro                                                   wait
diff --git a/fstab.ranchu.early.arm b/fstab.ranchu.early.arm
new file mode 100644
index 0000000..5854b59
--- /dev/null
+++ b/fstab.ranchu.early.arm
@@ -0,0 +1,6 @@
+# Android fstab file.
+#<src>                                                  <mnt_point>         <type>    <mnt_flags and options>                              <fs_mgr_flags>
+# The filesystem that contains the filesystem checker binary (typically /system) cannot
+# specify MF_CHECK, and must come before any filesystems that do specify MF_CHECK
+/dev/block/vda                                          /system             ext4      ro                                                   wait
+/dev/block/vdd                                          /vendor             ext4      ro                                                   wait
diff --git a/gatekeeper/Android.mk b/gatekeeper/Android.mk
new file mode 100644
index 0000000..dc995e4
--- /dev/null
+++ b/gatekeeper/Android.mk
@@ -0,0 +1,46 @@
+#
+# Copyright (C) 2015 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)
+
+include $(CLEAR_VARS)
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE := gatekeeper.ranchu
+LOCAL_MODULE_RELATIVE_PATH := hw
+
+LOCAL_CFLAGS := -Wall -Wextra -Werror -Wunused
+LOCAL_SRC_FILES := \
+	module.cpp \
+	SoftGateKeeperDevice.cpp
+
+
+LOCAL_SHARED_LIBRARIES := \
+	libbinder \
+	libgatekeeper \
+	liblog \
+	libhardware \
+	libbase \
+	libutils \
+	libcrypto \
+	libkeystore_binder \
+	libhidlbase \
+	libhidltransport \
+	libhwbinder \
+	android.hardware.gatekeeper@1.0 \
+
+LOCAL_STATIC_LIBRARIES := libscrypt_static
+LOCAL_C_INCLUDES := external/scrypt/lib/crypto
+include $(BUILD_SHARED_LIBRARY)
diff --git a/gatekeeper/SoftGateKeeper.h b/gatekeeper/SoftGateKeeper.h
new file mode 100644
index 0000000..2f4f4d7
--- /dev/null
+++ b/gatekeeper/SoftGateKeeper.h
@@ -0,0 +1,182 @@
+/*
+ * Copyright 2015 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 SOFT_GATEKEEPER_H_
+#define SOFT_GATEKEEPER_H_
+
+extern "C" {
+#include <openssl/rand.h>
+#include <openssl/sha.h>
+
+#include <crypto_scrypt.h>
+}
+
+#include <android-base/memory.h>
+#include <gatekeeper/gatekeeper.h>
+
+#include <iostream>
+#include <unordered_map>
+#include <memory>
+
+namespace gatekeeper {
+
+struct fast_hash_t {
+    uint64_t salt;
+    uint8_t digest[SHA256_DIGEST_LENGTH];
+};
+
+class SoftGateKeeper : public GateKeeper {
+public:
+    static const uint32_t SIGNATURE_LENGTH_BYTES = 32;
+
+    // scrypt params
+    static const uint64_t N = 16384;
+    static const uint32_t r = 8;
+    static const uint32_t p = 1;
+
+    static const int MAX_UINT_32_CHARS = 11;
+
+    SoftGateKeeper() {
+        key_.reset(new uint8_t[SIGNATURE_LENGTH_BYTES]);
+        memset(key_.get(), 0, SIGNATURE_LENGTH_BYTES);
+    }
+
+    virtual ~SoftGateKeeper() {
+    }
+
+    virtual bool GetAuthTokenKey(const uint8_t **auth_token_key,
+            uint32_t *length) const {
+        if (auth_token_key == NULL || length == NULL) return false;
+        uint8_t *auth_token_key_copy = new uint8_t[SIGNATURE_LENGTH_BYTES];
+        memcpy(auth_token_key_copy, key_.get(), SIGNATURE_LENGTH_BYTES);
+
+        *auth_token_key = auth_token_key_copy;
+        *length = SIGNATURE_LENGTH_BYTES;
+        return true;
+    }
+
+    virtual void GetPasswordKey(const uint8_t **password_key, uint32_t *length) {
+        if (password_key == NULL || length == NULL) return;
+        uint8_t *password_key_copy = new uint8_t[SIGNATURE_LENGTH_BYTES];
+        memcpy(password_key_copy, key_.get(), SIGNATURE_LENGTH_BYTES);
+
+        *password_key = password_key_copy;
+        *length = SIGNATURE_LENGTH_BYTES;
+    }
+
+    virtual void ComputePasswordSignature(uint8_t *signature, uint32_t signature_length,
+            const uint8_t *, uint32_t, const uint8_t *password,
+            uint32_t password_length, salt_t salt) const {
+        if (signature == NULL) return;
+        crypto_scrypt(password, password_length, reinterpret_cast<uint8_t *>(&salt),
+                sizeof(salt), N, r, p, signature, signature_length);
+    }
+
+    virtual void GetRandom(void *random, uint32_t requested_length) const {
+        if (random == NULL) return;
+        RAND_pseudo_bytes((uint8_t *) random, requested_length);
+    }
+
+    virtual void ComputeSignature(uint8_t *signature, uint32_t signature_length,
+            const uint8_t *, uint32_t, const uint8_t *, const uint32_t) const {
+        if (signature == NULL) return;
+        memset(signature, 0, signature_length);
+    }
+
+    virtual uint64_t GetMillisecondsSinceBoot() const {
+        struct timespec time;
+        int res = clock_gettime(CLOCK_BOOTTIME, &time);
+        if (res < 0) return 0;
+        return (time.tv_sec * 1000) + (time.tv_nsec / 1000 / 1000);
+    }
+
+    virtual bool IsHardwareBacked() const {
+        return false;
+    }
+
+    virtual bool GetFailureRecord(uint32_t uid, secure_id_t user_id, failure_record_t *record,
+            bool /* secure */) {
+        failure_record_t *stored = &failure_map_[uid];
+        if (user_id != stored->secure_user_id) {
+            stored->secure_user_id = user_id;
+            stored->last_checked_timestamp = 0;
+            stored->failure_counter = 0;
+        }
+        memcpy(record, stored, sizeof(*record));
+        return true;
+    }
+
+    virtual bool ClearFailureRecord(uint32_t uid, secure_id_t user_id, bool /* secure */) {
+        failure_record_t *stored = &failure_map_[uid];
+        stored->secure_user_id = user_id;
+        stored->last_checked_timestamp = 0;
+        stored->failure_counter = 0;
+        return true;
+    }
+
+    virtual bool WriteFailureRecord(uint32_t uid, failure_record_t *record, bool /* secure */) {
+        failure_map_[uid] = *record;
+        return true;
+    }
+
+    fast_hash_t ComputeFastHash(const SizedBuffer &password, uint64_t salt) {
+        fast_hash_t fast_hash;
+        size_t digest_size = password.length + sizeof(salt);
+        std::unique_ptr<uint8_t[]> digest(new uint8_t[digest_size]);
+        memcpy(digest.get(), &salt, sizeof(salt));
+        memcpy(digest.get() + sizeof(salt), password.buffer.get(), password.length);
+
+        SHA256(digest.get(), digest_size, (uint8_t *) &fast_hash.digest);
+
+        fast_hash.salt = salt;
+        return fast_hash;
+    }
+
+    bool VerifyFast(const fast_hash_t &fast_hash, const SizedBuffer &password) {
+        fast_hash_t computed = ComputeFastHash(password, fast_hash.salt);
+        return memcmp(computed.digest, fast_hash.digest, SHA256_DIGEST_LENGTH) == 0;
+    }
+
+    bool DoVerify(const password_handle_t *expected_handle, const SizedBuffer &password) {
+        uint64_t user_id = android::base::get_unaligned<secure_id_t>(&expected_handle->user_id);
+        FastHashMap::const_iterator it = fast_hash_map_.find(user_id);
+        if (it != fast_hash_map_.end() && VerifyFast(it->second, password)) {
+            return true;
+        } else {
+            if (GateKeeper::DoVerify(expected_handle, password)) {
+                uint64_t salt;
+                GetRandom(&salt, sizeof(salt));
+                fast_hash_map_[user_id] = ComputeFastHash(password, salt);
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+private:
+
+    typedef std::unordered_map<uint32_t, failure_record_t> FailureRecordMap;
+    typedef std::unordered_map<uint64_t, fast_hash_t> FastHashMap;
+
+    std::unique_ptr<uint8_t[]> key_;
+    FailureRecordMap failure_map_;
+    FastHashMap fast_hash_map_;
+};
+}
+
+#endif // SOFT_GATEKEEPER_H_
diff --git a/gatekeeper/SoftGateKeeperDevice.cpp b/gatekeeper/SoftGateKeeperDevice.cpp
new file mode 100644
index 0000000..3dc6997
--- /dev/null
+++ b/gatekeeper/SoftGateKeeperDevice.cpp
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2015 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 "SoftGateKeeper.h"
+#include "SoftGateKeeperDevice.h"
+
+namespace goldfish {
+
+int SoftGateKeeperDevice::enroll(uint32_t uid,
+            const uint8_t *current_password_handle, uint32_t current_password_handle_length,
+            const uint8_t *current_password, uint32_t current_password_length,
+            const uint8_t *desired_password, uint32_t desired_password_length,
+            uint8_t **enrolled_password_handle, uint32_t *enrolled_password_handle_length) {
+
+    if (enrolled_password_handle == NULL || enrolled_password_handle_length == NULL ||
+            desired_password == NULL || desired_password_length == 0)
+        return -EINVAL;
+
+    // Current password and current password handle go together
+    if (current_password_handle == NULL || current_password_handle_length == 0 ||
+            current_password == NULL || current_password_length == 0) {
+        current_password_handle = NULL;
+        current_password_handle_length = 0;
+        current_password = NULL;
+        current_password_length = 0;
+    }
+
+    SizedBuffer desired_password_buffer(desired_password_length);
+    memcpy(desired_password_buffer.buffer.get(), desired_password, desired_password_length);
+
+    SizedBuffer current_password_handle_buffer(current_password_handle_length);
+    if (current_password_handle) {
+        memcpy(current_password_handle_buffer.buffer.get(), current_password_handle,
+                current_password_handle_length);
+    }
+
+    SizedBuffer current_password_buffer(current_password_length);
+    if (current_password) {
+        memcpy(current_password_buffer.buffer.get(), current_password, current_password_length);
+    }
+
+    EnrollRequest request(uid, &current_password_handle_buffer, &desired_password_buffer,
+            &current_password_buffer);
+    EnrollResponse response;
+
+    impl_->Enroll(request, &response);
+
+    if (response.error == ERROR_RETRY) {
+        return response.retry_timeout;
+    } else if (response.error != ERROR_NONE) {
+        return -EINVAL;
+    }
+
+    *enrolled_password_handle = response.enrolled_password_handle.buffer.release();
+    gatekeeper::password_handle_t *handle =
+                    reinterpret_cast<gatekeeper::password_handle_t *>(*enrolled_password_handle);
+    //FIXIT: We need to move this module to host with gatekeeper pipe
+    handle->hardware_backed = true;
+
+    *enrolled_password_handle_length = response.enrolled_password_handle.length;
+    return 0;
+}
+
+int SoftGateKeeperDevice::verify(uint32_t uid,
+        uint64_t challenge, const uint8_t *enrolled_password_handle,
+        uint32_t enrolled_password_handle_length, const uint8_t *provided_password,
+        uint32_t provided_password_length, uint8_t **auth_token, uint32_t *auth_token_length,
+        bool *request_reenroll) {
+
+    if (enrolled_password_handle == NULL ||
+            provided_password == NULL) {
+        return -EINVAL;
+    }
+
+    SizedBuffer password_handle_buffer(enrolled_password_handle_length);
+    memcpy(password_handle_buffer.buffer.get(), enrolled_password_handle,
+            enrolled_password_handle_length);
+    SizedBuffer provided_password_buffer(provided_password_length);
+    memcpy(provided_password_buffer.buffer.get(), provided_password, provided_password_length);
+
+    VerifyRequest request(uid, challenge, &password_handle_buffer, &provided_password_buffer);
+    VerifyResponse response;
+
+    impl_->Verify(request, &response);
+
+    if (response.error == ERROR_RETRY) {
+        return response.retry_timeout;
+    } else if (response.error != ERROR_NONE) {
+        return -EINVAL;
+    }
+
+    if (auth_token != NULL && auth_token_length != NULL) {
+       *auth_token = response.auth_token.buffer.release();
+       *auth_token_length = response.auth_token.length;
+    }
+
+    if (request_reenroll != NULL) {
+        *request_reenroll = response.request_reenroll;
+    }
+
+    return 0;
+}
+
+} // namespace goldfish
diff --git a/gatekeeper/SoftGateKeeperDevice.h b/gatekeeper/SoftGateKeeperDevice.h
new file mode 100644
index 0000000..af3a1bc
--- /dev/null
+++ b/gatekeeper/SoftGateKeeperDevice.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2015 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 SOFT_GATEKEEPER_DEVICE_H_
+#define SOFT_GATEKEEPER_DEVICE_H_
+
+#include "SoftGateKeeper.h"
+
+#include <memory>
+
+using namespace gatekeeper;
+
+namespace goldfish {
+
+/**
+ * Software based GateKeeper implementation
+ */
+class SoftGateKeeperDevice {
+public:
+    SoftGateKeeperDevice() {
+        impl_.reset(new SoftGateKeeper());
+    }
+
+   // Wrappers to translate the gatekeeper HAL API to the Kegyuard Messages API.
+
+    /**
+     * Enrolls password_payload, which should be derived from a user selected pin or password,
+     * with the authentication factor private key used only for enrolling authentication
+     * factor data.
+     *
+     * Returns: 0 on success or an error code less than 0 on error.
+     * On error, enrolled_password_handle will not be allocated.
+     */
+    int enroll(uint32_t uid,
+            const uint8_t *current_password_handle, uint32_t current_password_handle_length,
+            const uint8_t *current_password, uint32_t current_password_length,
+            const uint8_t *desired_password, uint32_t desired_password_length,
+            uint8_t **enrolled_password_handle, uint32_t *enrolled_password_handle_length);
+
+    /**
+     * Verifies provided_password matches enrolled_password_handle.
+     *
+     * Implementations of this module may retain the result of this call
+     * to attest to the recency of authentication.
+     *
+     * On success, writes the address of a verification token to auth_token,
+     * usable to attest password verification to other trusted services. Clients
+     * may pass NULL for this value.
+     *
+     * Returns: 0 on success or an error code less than 0 on error
+     * On error, verification token will not be allocated
+     */
+    int verify(uint32_t uid, uint64_t challenge,
+            const uint8_t *enrolled_password_handle, uint32_t enrolled_password_handle_length,
+            const uint8_t *provided_password, uint32_t provided_password_length,
+            uint8_t **auth_token, uint32_t *auth_token_length, bool *request_reenroll);
+private:
+    std::unique_ptr<SoftGateKeeper> impl_;
+};
+
+} // namespace gatekeeper
+
+#endif //SOFT_GATEKEEPER_DEVICE_H_
diff --git a/gatekeeper/module.cpp b/gatekeeper/module.cpp
new file mode 100644
index 0000000..787d3a5
--- /dev/null
+++ b/gatekeeper/module.cpp
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2015 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 <hardware/hardware.h>
+#include <hardware/gatekeeper.h>
+#define LOG_TAG "GoldfishGatekeeper"
+#include <cutils/log.h>
+
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include "SoftGateKeeper.h"
+#include "SoftGateKeeperDevice.h"
+
+using goldfish::SoftGateKeeperDevice;
+
+struct goldfish_gatekeeper_device {
+    gatekeeper_device device;
+    SoftGateKeeperDevice *s_gatekeeper;
+};
+
+static goldfish_gatekeeper_device s_device;
+
+static int enroll(const struct gatekeeper_device *dev __unused, uint32_t uid,
+            const uint8_t *current_password_handle, uint32_t current_password_handle_length,
+            const uint8_t *current_password, uint32_t current_password_length,
+            const uint8_t *desired_password, uint32_t desired_password_length,
+            uint8_t **enrolled_password_handle, uint32_t *enrolled_password_handle_length) {
+
+    SoftGateKeeperDevice *s_gatekeeper = ((goldfish_gatekeeper_device*)(dev))->s_gatekeeper;
+    ALOGE("called %s with gate keeper %p device %p\n", __func__, s_gatekeeper, dev);
+    if (s_gatekeeper == nullptr)  {
+        abort();
+        return -EINVAL;
+    }
+
+    return s_gatekeeper->enroll(uid,
+            current_password_handle, current_password_handle_length,
+            current_password, current_password_length,
+            desired_password, desired_password_length,
+            enrolled_password_handle, enrolled_password_handle_length);
+}
+
+static int verify(const struct gatekeeper_device *dev __unused, uint32_t uid, uint64_t challenge,
+            const uint8_t *enrolled_password_handle, uint32_t enrolled_password_handle_length,
+            const uint8_t *provided_password, uint32_t provided_password_length,
+            uint8_t **auth_token, uint32_t *auth_token_length, bool *request_reenroll) {
+    SoftGateKeeperDevice *s_gatekeeper = ((goldfish_gatekeeper_device*)(dev))->s_gatekeeper;
+    ALOGE("called %s with gate keeper %p device %p\n", __func__, s_gatekeeper, dev);
+    if (s_gatekeeper == nullptr) return -EINVAL;
+    return s_gatekeeper->verify(uid, challenge,
+            enrolled_password_handle, enrolled_password_handle_length,
+            provided_password, provided_password_length,
+            auth_token, auth_token_length, request_reenroll);
+}
+
+static int close_device(hw_device_t* dev __unused) {
+    SoftGateKeeperDevice *s_gatekeeper = ((goldfish_gatekeeper_device*)(dev))->s_gatekeeper;
+    if (s_gatekeeper == nullptr) return 0;
+    delete s_gatekeeper;
+    s_gatekeeper = nullptr;
+    ALOGE("called %s with gate keeper %p device %p\n", __func__, s_gatekeeper, dev);
+    return 0;
+}
+
+static int goldfish_gatekeeper_open(const hw_module_t *module, const char *name,
+        hw_device_t **device) {
+
+    if (strcmp(name, HARDWARE_GATEKEEPER) != 0) {
+        abort();
+        return -EINVAL;
+    }
+
+    memset(&s_device, 0, sizeof(s_device));
+
+    SoftGateKeeperDevice *s_gatekeeper = new SoftGateKeeperDevice();
+    if (s_gatekeeper == nullptr) return -ENOMEM;
+
+    s_device.s_gatekeeper = s_gatekeeper;
+
+    s_device.device.common.tag = HARDWARE_DEVICE_TAG;
+    s_device.device.common.version = 1;
+    s_device.device.common.module = const_cast<hw_module_t *>(module);
+    s_device.device.common.close = close_device;
+
+    s_device.device.enroll = enroll;
+    s_device.device.verify = verify;
+    s_device.device.delete_user = nullptr;
+    s_device.device.delete_all_users = nullptr;
+
+    *device = &s_device.device.common;
+    ALOGE("called %s with gate keeper %p device %p\n", __func__, s_gatekeeper, *device);
+
+    return 0;
+}
+
+static struct hw_module_methods_t gatekeeper_module_methods = {
+    .open = goldfish_gatekeeper_open,
+};
+
+struct gatekeeper_module HAL_MODULE_INFO_SYM __attribute__((visibility("default"))) = {
+    .common = {
+        .tag = HARDWARE_MODULE_TAG,
+        .module_api_version = GATEKEEPER_MODULE_API_VERSION_0_1,
+        .hal_api_version = HARDWARE_HAL_API_VERSION,
+        .id = GATEKEEPER_HARDWARE_MODULE_ID,
+        .name = "Goldfish GateKeeper HAL",
+        .author = "The Android Open Source Project",
+        .methods = &gatekeeper_module_methods,
+        .dso = 0,
+        .reserved = {}
+    },
+};
diff --git a/gps/Android.mk b/gps/Android.mk
index c143981..d1b593a 100644
--- a/gps/Android.mk
+++ b/gps/Android.mk
@@ -24,6 +24,7 @@
 # hw/<GPS_HARDWARE_MODULE_ID>.<ro.hardware>.so
 include $(CLEAR_VARS)
 
+LOCAL_VENDOR_MODULE := true
 LOCAL_MODULE_RELATIVE_PATH := hw
 LOCAL_CFLAGS += -DQEMU_HARDWARE
 LOCAL_SHARED_LIBRARIES := liblog libcutils libhardware
@@ -39,6 +40,7 @@
 
 include $(CLEAR_VARS)
 
+LOCAL_VENDOR_MODULE := true
 LOCAL_MODULE_RELATIVE_PATH := hw
 LOCAL_CFLAGS += -DQEMU_HARDWARE
 LOCAL_SHARED_LIBRARIES := liblog libcutils libhardware
diff --git a/gps/gps_qemu.c b/gps/gps_qemu.c
index e623418..dc7351f 100644
--- a/gps/gps_qemu.c
+++ b/gps/gps_qemu.c
@@ -240,7 +240,6 @@
     if (cb != NULL && r->fix.flags != 0) {
         D("%s: sending latest fix to new callback", __FUNCTION__);
         r->callback( &r->fix );
-        r->fix.flags = 0;
     }
 }
 
@@ -466,6 +465,7 @@
         Token  tok_altitude      = nmea_tokenizer_get(tzer,9);
         Token  tok_altitudeUnits = nmea_tokenizer_get(tzer,10);
 
+        r->fix.flags = 0;
         nmea_reader_update_time(r, tok_time);
         nmea_reader_update_latlong(r, tok_latitude,
                                       tok_latitudeHemi.p[0],
@@ -489,6 +489,7 @@
         D("in RMC, fixStatus=%c", tok_fixStatus.p[0]);
         if (tok_fixStatus.p[0] == 'A')
         {
+            r->fix.flags = 0;
             nmea_reader_update_date( r, tok_date, tok_time );
 
             nmea_reader_update_latlong( r, tok_latitude,
@@ -536,7 +537,6 @@
 #endif
         if (r->callback) {
             r->callback( &r->fix );
-            r->fix.flags = 0;
         }
         else {
             D("no callback, keeping data until needed !");
@@ -688,6 +688,17 @@
     int         started    = 0;
     int         gps_fd     = state->fd;
     int         control_fd = state->control[1];
+    GpsStatus gps_status;
+    gps_status.size = sizeof(gps_status);
+    GpsSvStatus  gps_sv_status;
+    memset(&gps_sv_status, 0, sizeof(gps_sv_status));
+    gps_sv_status.size = sizeof(gps_sv_status);
+    gps_sv_status.num_svs = 1;
+    gps_sv_status.sv_list[0].size = sizeof(gps_sv_status.sv_list[0]);
+    gps_sv_status.sv_list[0].prn = 17;
+    gps_sv_status.sv_list[0].snr = 60.0;
+    gps_sv_status.sv_list[0].elevation = 30.0;
+    gps_sv_status.sv_list[0].azimuth = 30.0;
 
     nmea_reader_init( reader );
 
@@ -702,7 +713,15 @@
         struct epoll_event   events[2];
         int                  ne, nevents;
 
-        nevents = epoll_wait( epoll_fd, events, 2, -1 );
+        int timeout = -1;
+        if (gps_status.status == GPS_STATUS_SESSION_BEGIN) {
+            timeout = 10 * 1000; // 10 seconds
+        }
+        nevents = epoll_wait( epoll_fd, events, 2, timeout );
+        if (state->callbacks.sv_status_cb) {
+            state->callbacks.sv_status_cb(&gps_sv_status);
+        }
+        // update satilite info
         if (nevents < 0) {
             if (errno != EINTR)
                 ALOGE("epoll_wait() unexpected error: %s", strerror(errno));
@@ -735,6 +754,10 @@
                             D("gps thread starting  location_cb=%p", state->callbacks.location_cb);
                             started = 1;
                             nmea_reader_set_callback( reader, state->callbacks.location_cb );
+                            gps_status.status = GPS_STATUS_SESSION_BEGIN;
+                            if (state->callbacks.status_cb) {
+                                state->callbacks.status_cb(&gps_status);
+                            }
                         }
                     }
                     else if (cmd == CMD_STOP) {
@@ -742,6 +765,10 @@
                             D("gps thread stopping");
                             started = 0;
                             nmea_reader_set_callback( reader, NULL );
+                            gps_status.status = GPS_STATUS_SESSION_END;
+                            if (state->callbacks.status_cb) {
+                                state->callbacks.status_cb(&gps_status);
+                            }
                         }
                     }
                 }
@@ -807,6 +834,16 @@
 
     state->callbacks = *callbacks;
 
+    // Explicitly initialize capabilities
+    state->callbacks.set_capabilities_cb(0);
+
+
+    // Setup system info, we are pre 2016 hardware.
+    GnssSystemInfo sysinfo;
+    sysinfo.size = sizeof(GnssSystemInfo);
+    sysinfo.year_of_hw = 2015;
+    state->callbacks.set_system_info_cb(&sysinfo);
+
     D("gps state initialized");
     return;
 
diff --git a/hwcomposer/Android.mk b/hwcomposer/Android.mk
index 5f20c58..55c66bb 100644
--- a/hwcomposer/Android.mk
+++ b/hwcomposer/Android.mk
@@ -17,6 +17,7 @@
 LOCAL_PATH:= $(call my-dir)
 
 include $(CLEAR_VARS)
+LOCAL_VENDOR_MODULE := true
 emulator_hwcomposer_shared_libraries := \
     liblog \
     libutils \
@@ -54,6 +55,7 @@
 # RANCHU BUILD
 include $(CLEAR_VARS)
 
+LOCAL_VENDOR_MODULE := true
 LOCAL_SHARED_LIBRARIES := $(emulator_hwcomposer_shared_libraries)
 LOCAL_SRC_FILES := $(emulator_hwcomposer_src_files)
 LOCAL_CFLAGS := $(emulator_hwcomposer_cflags)
diff --git a/include/qemu_pipe.h b/include/qemu_pipe.h
index d76ba3b..1056bb3 100644
--- a/include/qemu_pipe.h
+++ b/include/qemu_pipe.h
@@ -81,7 +81,7 @@
 {
     char  buff[256];
     int   buffLen;
-    int   fd, ret;
+    int   fd;
 
     if (pipeName == NULL || pipeName[0] == '\0') {
         errno = EINVAL;
diff --git a/include/qemud.h b/include/qemud.h
index 71ec3bf..c6327ee 100644
--- a/include/qemud.h
+++ b/include/qemud.h
@@ -36,7 +36,10 @@
  * that sends its formatted string argument(s) to the log.
  * If not, ignore the traces.
  */
-#  define  D(...) ((void)0)
+#ifndef D
+#  define  D(...)   do{}while(0)
+#endif
+
 
 static __inline__ int
 qemud_channel_open(const char*  name)
@@ -108,7 +111,7 @@
 qemud_channel_recv(int  fd, void*  msg, int  msgsize)
 {
     char  header[5];
-    int   size, avail;
+    int   size;
 
     if (!ReadFully(fd, header, 4)) {
         D("can't read qemud frame header: %s", strerror(errno));
diff --git a/init.goldfish.rc b/init.goldfish.rc
index b1613a4..db958d7 100644
--- a/init.goldfish.rc
+++ b/init.goldfish.rc
@@ -112,7 +112,7 @@
     user system
 
 service bugreport /system/bin/dumpstate -d -p -B \
-        -o /data/data/com.android.shell/files/bugreports/bugreport
+        -o /data/user_de/0/com.android.shell/files/bugreports/bugreport
     class main
     disabled
     oneshot
diff --git a/init.ranchu-net.sh b/init.ranchu-net.sh
index e4347d3..a14ab18 100755
--- a/init.ranchu-net.sh
+++ b/init.ranchu-net.sh
@@ -1,4 +1,4 @@
-#!/system/bin/sh
+#!/vendor/bin/sh
 
 # Setup networking when boot starts
 ifconfig eth0 10.0.2.15 netmask 255.255.255.0 up
diff --git a/init.ranchu.rc b/init.ranchu.rc
index c9abe1d..c3cc065 100644
--- a/init.ranchu.rc
+++ b/init.ranchu.rc
@@ -12,6 +12,7 @@
 on post-fs-data
     setprop vold.post_fs_data_done 1
 
+
 on boot
     setprop net.eth0.gw 10.0.2.2
     setprop net.eth0.dns1 10.0.2.3
@@ -71,13 +72,13 @@
     chown root system /sys/power/wake_lock
     chown root system /sys/power/wake_unlock
 
-service ranchu-setup /system/bin/init.ranchu-core.sh
+service ranchu-setup /vendor/bin/init.ranchu-core.sh
     class core
     user root
     group root
     oneshot
 
-service ranchu-net /system/bin/init.ranchu-net.sh
+service ranchu-net /vendor/bin/init.ranchu-net.sh
     class late_start
     user root
     group root wakelock
@@ -89,7 +90,7 @@
 # might read them (e.g. surface flinger), so define it in
 # class 'core'
 #
-service qemu-props /system/bin/qemu-props
+service qemu-props /vendor/bin/qemu-props
     class core
     user root
     group root
@@ -115,7 +116,7 @@
     user system
 
 service bugreport /system/bin/dumpstate -d -p -B \
-        -o /data/data/com.android.shell/files/bugreports/bugreport
+        -o /data/user_de/0/com.android.shell/files/bugreports/bugreport
     class main
     disabled
     oneshot
diff --git a/keymaster/Android.mk b/keymaster/Android.mk
new file mode 100644
index 0000000..600e32d
--- /dev/null
+++ b/keymaster/Android.mk
@@ -0,0 +1,47 @@
+# Copyright (C) 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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_VENDOR_MODULE := true
+ifeq ($(USE_32_BIT_KEYSTORE), true)
+LOCAL_MULTILIB := 32
+endif
+LOCAL_MODULE := libgoldfishkeymaster
+LOCAL_SRC_FILES := keymaster_openssl.c
+LOCAL_C_INCLUDES := system/security/keystore \
+                    $(LOCAL_PATH)/../include
+LOCAL_CFLAGS = -fvisibility=hidden -Wall -Werror
+LOCAL_SHARED_LIBRARIES := libcrypto liblog libkeystore_binder
+LOCAL_MODULE_TAGS := optional
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+include $(BUILD_SHARED_LIBRARY)
+
+# Emulated keymaster - ranchu build##########################################
+
+include $(CLEAR_VARS)
+LOCAL_VENDOR_MODULE := true
+ifeq ($(USE_32_BIT_KEYSTORE), true)
+LOCAL_MULTILIB := 32
+endif
+LOCAL_MODULE := keystore.ranchu
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_SRC_FILES := module.cpp
+LOCAL_C_INCLUDES := system/security/keystore
+LOCAL_CFLAGS = -fvisibility=hidden -Wall -Werror
+LOCAL_SHARED_LIBRARIES := libcrypto liblog libkeystore_binder libgoldfishkeymaster
+LOCAL_MODULE_TAGS := optional
+include $(BUILD_SHARED_LIBRARY)
diff --git a/keymaster/keymaster_openssl.c b/keymaster/keymaster_openssl.c
new file mode 100644
index 0000000..69c9572
--- /dev/null
+++ b/keymaster/keymaster_openssl.c
@@ -0,0 +1,497 @@
+/*
+ * Copyright (C) 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.
+ */
+#include <assert.h>
+#include <errno.h>
+#include <hardware/keymaster_common.h>
+#include <malloc.h>
+#include <pthread.h>
+#include <stdint.h>
+#include <string.h>
+
+#define LOG_TAG "OpenSSLKeyMaster"
+#include <cutils/log.h>
+
+#ifdef DEBUG
+#   define D(...)   ALOGD(__VA_ARGS__)
+#else
+#   define D(...)   ((void)0)
+#endif
+
+#include <hardware/hardware.h>
+#include <hardware/keymaster0.h>
+#include "qemud.h"
+
+#define KEYMASTER_SERVICE_NAME "KeymasterService"
+
+typedef struct qemu_keymaster0_device_t {
+    keymaster0_device_t device; // "inheritance", must be the first member
+    int qchanfd;
+    pthread_mutex_t lock;
+} qemu_keymaster0_device_t;
+
+enum {
+        GenerateKeypair = 0,
+        ImportKeypair,
+        GetKeypairPublic,
+        SignData,
+        VerifyData,
+};
+
+static int32_t unwrap_key_type(const uint8_t* key_blob) {
+    int32_t key_type = 0;
+    const uint8_t* p = key_blob;
+    size_t i;
+    for (i = 0; i < sizeof(key_type); i++) {
+        key_type = (key_type << 8) | *p++;
+    }
+    return key_type;
+}
+
+static int keymaster_fd_write(int fd, const void* buff, int len) {
+    int ret = WriteFully(fd, buff, len);
+    assert(ret);
+    return ret;
+}
+
+static int keymaster_fd_read(int fd, void* buff, int len) {
+    int ret = ReadFully(fd, buff, len);
+    assert(ret);
+    return ret;
+}
+
+static int EVP2EncoderType(int evpType) {
+    switch (evpType) {
+        case 6: // RSA
+            return TYPE_RSA;
+        case 408: // EC:
+            return TYPE_EC;
+        case 116: // DSA:
+            return TYPE_DSA;
+        default:
+            D("Unsupported evp key type %d", evpType);
+            return -1;
+    }
+}
+
+static int gen_param_length(int type, const void* params) {
+    switch (type) {
+        case TYPE_DSA: {
+            keymaster_dsa_keygen_params_t* dsa_params =
+                    (keymaster_dsa_keygen_params_t*)params;
+            return 4 + 4 + 4 + 4 + dsa_params->generator_len
+                    + dsa_params->prime_p_len
+                    + dsa_params->prime_q_len;
+        }
+        case TYPE_EC:
+            return 4;
+        case TYPE_RSA:
+            return 8 + 4;
+        default:
+            D("Unsupported key type %d", type);
+            return -1;
+    }
+}
+
+static int sign_param_length(int type) {
+    switch (type) {
+        case TYPE_DSA:
+            return sizeof(keymaster_digest_algorithm_t);
+            break;
+        case TYPE_EC:
+            return sizeof(keymaster_digest_algorithm_t);
+            break;
+        case TYPE_RSA:
+            return sizeof(keymaster_digest_algorithm_t)
+                    + sizeof(keymaster_rsa_padding_t);
+            break;
+        default:
+            D("Unsupported key type %d", type);
+            return -1;
+    }
+}
+
+static void write_gen_param(int fd,
+    const keymaster_keypair_t type,
+    const void* key_params) {
+    switch (type) {
+        case TYPE_DSA: {
+            keymaster_dsa_keygen_params_t* dsa_params =
+                (keymaster_dsa_keygen_params_t*)key_params;
+
+            keymaster_fd_write(fd, (void*)&dsa_params->key_size,
+                sizeof(dsa_params->key_size));
+
+            keymaster_fd_write(fd, (void*)&dsa_params->generator_len,
+                sizeof(dsa_params->generator_len));
+            keymaster_fd_write(fd, (void*)&dsa_params->prime_p_len,
+                sizeof(dsa_params->prime_p_len));
+            keymaster_fd_write(fd, (void*)&dsa_params->prime_q_len,
+                sizeof(dsa_params->prime_q_len));
+
+            keymaster_fd_write(fd, (void*)dsa_params->generator,
+                dsa_params->generator_len);
+            keymaster_fd_write(fd, (void*)dsa_params->prime_p,
+                dsa_params->prime_p_len);
+            keymaster_fd_write(fd, (void*)dsa_params->prime_q,
+                dsa_params->prime_q_len);
+            break;
+        }
+        case TYPE_EC: {
+            keymaster_ec_keygen_params_t* ec_params =
+                (keymaster_ec_keygen_params_t*)key_params;
+            keymaster_fd_write(fd, (void*)&ec_params->field_size,
+                sizeof(ec_params->field_size));
+            break;
+        }
+        case TYPE_RSA: {
+            keymaster_rsa_keygen_params_t* rsa_params =
+                (keymaster_rsa_keygen_params_t*)key_params;
+            keymaster_fd_write(fd, (void*)&rsa_params->modulus_size,
+                sizeof(rsa_params->modulus_size));
+            keymaster_fd_write(fd, (void*)&rsa_params->public_exponent,
+                sizeof(rsa_params->public_exponent));
+            break;
+        }
+        default:
+            D("Unsupported key type %d", type);
+            return;
+    }
+}
+
+static void write_sign_param(int fd,
+    const keymaster_keypair_t type,
+    const void* key_params) {
+    switch (type) {
+        case TYPE_DSA: {
+            keymaster_dsa_sign_params_t* dsa_params =
+                (keymaster_dsa_sign_params_t*)key_params;
+            keymaster_fd_write(fd, (void*)&dsa_params->digest_type,
+                sizeof(dsa_params->digest_type));
+            break;
+        }
+        case TYPE_EC: {
+            keymaster_ec_sign_params_t* ec_params =
+                (keymaster_ec_sign_params_t*)key_params;
+            keymaster_fd_write(fd, (void*)&ec_params->digest_type,
+                sizeof(ec_params->digest_type));
+            break;
+        }
+        case TYPE_RSA: {
+            keymaster_rsa_sign_params_t* rsa_params =
+                (keymaster_rsa_sign_params_t*)key_params;
+            keymaster_fd_write(fd, (void*)&rsa_params->digest_type,
+                sizeof(rsa_params->digest_type));
+            keymaster_fd_write(fd, (void*)&rsa_params->padding_type,
+                sizeof(rsa_params->padding_type));
+            break;
+        }
+        default:
+            D("Unsupported key type %d", type);
+            return;
+    }
+}
+
+static int openssl_generate_keypair(const keymaster0_device_t* device,
+        const keymaster_keypair_t key_type, const void* key_params,
+        uint8_t** key_blob, size_t* key_blob_length) {
+    D("generate keypair");
+    if (key_params == NULL) {
+        ALOGE("key_params == null");
+        return -1;
+    }
+    const uint32_t cmd = GenerateKeypair;
+    int32_t _key_type = (int)key_type;
+    int32_t key_params_len = gen_param_length(key_type, key_params);
+    if (key_params_len < 0) {
+        return -1;
+    }
+    qemu_keymaster0_device_t* qemu_dev = (qemu_keymaster0_device_t*)device;
+    pthread_mutex_lock(&qemu_dev->lock);
+    // send
+    const uint64_t cmdLen = sizeof(cmd) + sizeof(_key_type) + sizeof(key_params_len)
+            + key_params_len;
+    keymaster_fd_write(qemu_dev->qchanfd, (void*)&cmdLen, sizeof(cmdLen));
+    keymaster_fd_write(qemu_dev->qchanfd, (void*)&cmd, sizeof(cmd));
+    keymaster_fd_write(qemu_dev->qchanfd, (void*)&_key_type, sizeof(_key_type));
+    keymaster_fd_write(qemu_dev->qchanfd, (void*)&key_params_len, sizeof(key_params_len));
+    write_gen_param(qemu_dev->qchanfd, key_type, key_params);
+
+    // receive
+    uint32_t _key_blob_len = 0;
+    int32_t ret;
+    keymaster_fd_read(qemu_dev->qchanfd, &_key_blob_len, sizeof(_key_blob_len));
+    *key_blob_length = _key_blob_len;
+    if (_key_blob_len) {
+        *key_blob = malloc(_key_blob_len);
+        keymaster_fd_read(qemu_dev->qchanfd, *key_blob, _key_blob_len);
+    }
+    keymaster_fd_read(qemu_dev->qchanfd, &ret, sizeof(ret));
+
+    pthread_mutex_unlock(&qemu_dev->lock);
+    return ret;
+}
+
+static int openssl_import_keypair(const keymaster0_device_t* device,
+                                                                  const uint8_t* key,
+                                                                  const size_t key_length,
+                                                                  uint8_t** key_blob,
+                                                                  size_t* key_blob_length) {
+    D("import keypair");
+    if (key == NULL) {
+        ALOGW("input key == NULL");
+        return -1;
+    } else if (key_blob == NULL || key_blob_length == NULL) {
+        ALOGW("output key blob or length == NULL");
+        return -1;
+    }
+
+    const uint32_t cmd = ImportKeypair;
+    qemu_keymaster0_device_t* qemu_dev = (qemu_keymaster0_device_t*)device;
+    pthread_mutex_lock(&qemu_dev->lock);
+    // send
+    const uint32_t _key_length = (uint32_t)key_length;
+    const uint64_t cmdLen = sizeof(cmd) + sizeof(_key_length) + _key_length;
+
+    keymaster_fd_write(qemu_dev->qchanfd, (void*)&cmdLen, sizeof(cmdLen));
+    keymaster_fd_write(qemu_dev->qchanfd, (void*)&cmd, sizeof(cmd));
+    keymaster_fd_write(qemu_dev->qchanfd, (void*)&_key_length, sizeof(_key_length));
+    keymaster_fd_write(qemu_dev->qchanfd, (void*)key, key_length);
+
+    // receive
+    uint32_t _key_blob_len = 0;
+    int32_t ret;
+    keymaster_fd_read(qemu_dev->qchanfd, &_key_blob_len, sizeof(_key_blob_len));
+    *key_blob_length = _key_blob_len;
+    *key_blob = malloc(_key_blob_len);
+    keymaster_fd_read(qemu_dev->qchanfd, *key_blob, _key_blob_len);
+    keymaster_fd_read(qemu_dev->qchanfd, &ret, sizeof(ret));
+
+    pthread_mutex_unlock(&qemu_dev->lock);
+    return ret;
+}
+
+static int openssl_get_keypair_public(const keymaster0_device_t* device,
+        const uint8_t* key_blob, const size_t key_blob_length,
+        uint8_t** x509_data, size_t* x509_data_length) {
+    D("get keypair public");
+    if (x509_data == NULL || x509_data_length == NULL) {
+        ALOGW("output public key buffer == NULL");
+        return -1;
+    }
+
+    const uint32_t cmd = GetKeypairPublic;
+    qemu_keymaster0_device_t* qemu_dev = (qemu_keymaster0_device_t*)device;
+    pthread_mutex_lock(&qemu_dev->lock);
+    // send
+    const uint32_t _key_blob_length = (uint32_t)key_blob_length;
+    const uint64_t cmdLen = sizeof(cmd) + sizeof(_key_blob_length) +
+                            _key_blob_length;
+
+    keymaster_fd_write(qemu_dev->qchanfd, (void*)&cmdLen, sizeof(cmdLen));
+    keymaster_fd_write(qemu_dev->qchanfd, (void*)&cmd, sizeof(cmd));
+    keymaster_fd_write(qemu_dev->qchanfd, (void*)&_key_blob_length, sizeof(_key_blob_length));
+    keymaster_fd_write(qemu_dev->qchanfd, (void*)key_blob, _key_blob_length);
+
+    // receive
+    uint32_t _x509_data_length = 0;
+    int32_t ret;
+    keymaster_fd_read(qemu_dev->qchanfd, &_x509_data_length,
+            sizeof(_x509_data_length));
+    *x509_data_length = _x509_data_length;
+    if (_x509_data_length) {
+        *x509_data = malloc(_x509_data_length);
+        keymaster_fd_read(qemu_dev->qchanfd, *x509_data, _x509_data_length);
+    } else {
+        *x509_data = NULL;
+    }
+    keymaster_fd_read(qemu_dev->qchanfd, &ret, sizeof(ret));
+
+    pthread_mutex_unlock(&qemu_dev->lock);
+    return ret;
+}
+
+static int openssl_sign_data(const keymaster0_device_t* device, const void* params,
+        const uint8_t* key_blob,  const size_t key_blob_length,
+        const uint8_t* data, const size_t data_length,
+        uint8_t** signed_data, size_t* signed_data_length) {
+    D("sign data");
+    if (signed_data == NULL || signed_data_length == NULL) {
+        ALOGW("output signature buffer == NULL");
+        return -1;
+    }
+
+    int32_t key_type = EVP2EncoderType(unwrap_key_type(key_blob));
+    int32_t params_len = sign_param_length(key_type);
+    if (params_len < 0) {
+        return -1;
+    }
+
+    const uint32_t cmd = SignData;
+    qemu_keymaster0_device_t* qemu_dev = (qemu_keymaster0_device_t*)device;
+    pthread_mutex_lock(&qemu_dev->lock);
+    // send
+    const uint32_t _key_blob_length = (uint32_t)key_blob_length;
+    const uint32_t _data_length = (uint32_t)data_length;
+    const uint64_t cmdLen = sizeof(cmd) + sizeof(key_type) + sizeof(params_len) + params_len +
+                            sizeof(_key_blob_length) + _key_blob_length +
+                            sizeof(_data_length) + _data_length;
+
+    keymaster_fd_write(qemu_dev->qchanfd, (void*)&cmdLen, sizeof(cmdLen));
+    keymaster_fd_write(qemu_dev->qchanfd, (void*)&cmd, sizeof(cmd));
+    keymaster_fd_write(qemu_dev->qchanfd, (void*)&key_type, sizeof(key_type));
+    keymaster_fd_write(qemu_dev->qchanfd, (void*)&params_len, sizeof(params_len));
+    write_sign_param(qemu_dev->qchanfd, key_type, params);
+    keymaster_fd_write(qemu_dev->qchanfd, (void*)&_key_blob_length, sizeof(_key_blob_length));
+    keymaster_fd_write(qemu_dev->qchanfd, (void*)key_blob, _key_blob_length);
+    keymaster_fd_write(qemu_dev->qchanfd, (void*)&_data_length, sizeof(_data_length));
+    keymaster_fd_write(qemu_dev->qchanfd, (void*)data, _data_length);
+
+    // receive
+    uint32_t _signed_data_length = 0;
+    int32_t ret;
+    keymaster_fd_read(qemu_dev->qchanfd, &_signed_data_length,
+            sizeof(_signed_data_length));
+    *signed_data_length = _signed_data_length;
+    if (_signed_data_length) {
+        *signed_data = malloc(_signed_data_length);
+        keymaster_fd_read(qemu_dev->qchanfd, *signed_data, _signed_data_length);
+    }
+    keymaster_fd_read(qemu_dev->qchanfd, &ret, sizeof(ret));
+
+    pthread_mutex_unlock(&qemu_dev->lock);
+    return ret;
+}
+
+static int openssl_verify_data(const keymaster0_device_t* device, const void* params,
+        const uint8_t* key_blob, const size_t key_blob_length,
+        const uint8_t* signed_data, const size_t signed_data_length,
+        const uint8_t* signature, const size_t signature_length) {
+    D("verify data");
+    if (signed_data == NULL || signature == NULL) {
+        ALOGW("data or signature buffers == NULL");
+        return -1;
+    }
+
+    int32_t key_type = EVP2EncoderType(unwrap_key_type(key_blob));
+    int32_t params_len = sign_param_length(key_type);
+    if (params_len < 0) {
+        return -1;
+    }
+
+    const uint32_t cmd = VerifyData;
+    qemu_keymaster0_device_t* qemu_dev = (qemu_keymaster0_device_t*)device;
+    pthread_mutex_lock(&qemu_dev->lock);
+    // send
+    const uint32_t _key_blob_length = (uint32_t)key_blob_length;
+    const uint32_t _signed_data_length = (uint32_t)signed_data_length;
+    const uint32_t _signature_length = (uint32_t)signature_length;
+    const uint64_t cmdLen = sizeof(cmd) + sizeof(key_type) + sizeof(params_len) + params_len +
+                            sizeof(_key_blob_length) + _key_blob_length +
+                            sizeof(_signed_data_length) + _signed_data_length +
+                            sizeof(_signature_length) + _signature_length;
+
+    keymaster_fd_write(qemu_dev->qchanfd, (void*)&cmdLen, sizeof(cmdLen));
+    keymaster_fd_write(qemu_dev->qchanfd, (void*)&cmd, sizeof(cmd));
+    keymaster_fd_write(qemu_dev->qchanfd, (void*)&key_type, sizeof(key_type));
+    keymaster_fd_write(qemu_dev->qchanfd, (void*)&params_len, sizeof(params_len));
+    write_sign_param(qemu_dev->qchanfd, key_type, params);
+    keymaster_fd_write(qemu_dev->qchanfd, (void*)&_key_blob_length, sizeof(_key_blob_length));
+    keymaster_fd_write(qemu_dev->qchanfd, (void*)key_blob, _key_blob_length);
+    keymaster_fd_write(qemu_dev->qchanfd, (void*)&_signed_data_length, sizeof(_signed_data_length));
+    keymaster_fd_write(qemu_dev->qchanfd, (void*)signed_data, _signed_data_length);
+    keymaster_fd_write(qemu_dev->qchanfd, (void*)&_signature_length, sizeof(_signature_length));
+    keymaster_fd_write(qemu_dev->qchanfd, (void*)signature, _signature_length);
+
+    // receive
+    int32_t ret;
+    keymaster_fd_read(qemu_dev->qchanfd, &ret, sizeof(ret));
+
+    pthread_mutex_unlock(&qemu_dev->lock);
+    return ret;
+}
+
+/* Close an opened OpenSSL instance */
+static int openssl_close(hw_device_t* dev) {
+    D("close device");
+    qemu_keymaster0_device_t* qemu_dev = (qemu_keymaster0_device_t*)dev;
+    pthread_mutex_destroy(&qemu_dev->lock);
+    close(qemu_dev->qchanfd);
+    free(qemu_dev);
+    return 0;
+}
+
+/*
+ * Generic device handling
+ */
+static int openssl_open(const hw_module_t* module, const char* name,
+                        hw_device_t** device) {
+    D("open device");
+    if (strcmp(name, KEYSTORE_KEYMASTER) != 0)
+        return -EINVAL;
+
+    qemu_keymaster0_device_t* qemu_dev = calloc(1, sizeof(qemu_keymaster0_device_t));
+    if (qemu_dev == NULL)
+        return -ENOMEM;
+    keymaster0_device_t* dev = (keymaster0_device_t*)qemu_dev;
+
+    dev->common.tag = HARDWARE_DEVICE_TAG;
+    dev->common.version = 1;
+    dev->common.module = (struct hw_module_t*)module;
+    dev->common.close = openssl_close;
+
+    dev->flags = KEYMASTER_BLOBS_ARE_STANDALONE | KEYMASTER_SUPPORTS_DSA |
+                 KEYMASTER_SUPPORTS_EC;
+
+    dev->generate_keypair = openssl_generate_keypair;
+    dev->import_keypair = openssl_import_keypair;
+    dev->get_keypair_public = openssl_get_keypair_public;
+    dev->delete_keypair = NULL;
+    dev->delete_all = NULL;
+    dev->sign_data = openssl_sign_data;
+    dev->verify_data = openssl_verify_data;
+
+    // set up the pipe
+    qemu_dev->qchanfd = qemu_pipe_open(KEYMASTER_SERVICE_NAME);
+    if (qemu_dev->qchanfd < 0) {
+        ALOGE("keymaster: failed to get host connection while opening %s\n", name);
+        free(qemu_dev);
+        return -EIO;
+    }
+    pthread_mutex_init(&qemu_dev->lock, NULL);
+
+    *device = &dev->common;
+
+    return 0;
+}
+
+static struct hw_module_methods_t keystore_module_methods = {
+    .open = openssl_open,
+};
+
+struct keystore_module goldfishkeymaster_module __attribute__((visibility("default"))) = {
+    .common =
+        {
+         .tag = HARDWARE_MODULE_TAG,
+         .module_api_version = KEYMASTER_MODULE_API_VERSION_0_2,
+         .hal_api_version = HARDWARE_HAL_API_VERSION,
+         .id = KEYSTORE_HARDWARE_MODULE_ID,
+         .name = "Keymaster OpenSSL HAL",
+         .author = "The Android Open Source Project",
+         .methods = &keystore_module_methods,
+         .dso = 0,
+         .reserved = {},
+        },
+};
diff --git a/keymaster/module.cpp b/keymaster/module.cpp
new file mode 100644
index 0000000..97a15cc
--- /dev/null
+++ b/keymaster/module.cpp
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 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.
+ */
+#include <keystore/keystore.h>
+
+#include <hardware/hardware.h>
+#include <hardware/keymaster0.h>
+
+extern struct keystore_module goldfishkeymaster_module;
+struct keystore_module HAL_MODULE_INFO_SYM __attribute__((visibility("default")))
+    = goldfishkeymaster_module;
diff --git a/lights/Android.mk b/lights/Android.mk
index dadcabc..41ab150 100644
--- a/lights/Android.mk
+++ b/lights/Android.mk
@@ -17,11 +17,12 @@
 # HAL module implemenation, not prelinked and stored in
 # hw/<LIGHTS_HARDWARE_MODULE_ID>.<ro.hardware>.so
 include $(CLEAR_VARS)
+LOCAL_RENDOR_MODULE := true
 LOCAL_MODULE_RELATIVE_PATH := hw
 LOCAL_SHARED_LIBRARIES := liblog libcutils
 LOCAL_C_INC := lights_qemu.c
 LOCAL_C_INCLUDES += $(LOCAL_PATH)/../include
 LOCAL_SRC_FILES := lights_qemu.c
-LOCAL_MODULE := lights.goldfish
+LOCAL_MODULE := lights.ranchu
 LOCAL_CFLAGS += -DLIGHT_BACKLIGHT
 include $(BUILD_SHARED_LIBRARY)
diff --git a/manifest.xml b/manifest.xml
index 7d359a0..2b7e0d4 100644
--- a/manifest.xml
+++ b/manifest.xml
@@ -1,17 +1,71 @@
 <manifest version="1.0" type="device">
     <hal format="hidl">
         <name>android.hardware.drm</name>
-        <transport arch="32">passthrough</transport>
-        <impl level="generic"></impl>
+        <transport>hwbinder</transport>
         <version>1.0</version>
-        <!-- TODO(b/36371166): change to default -->
         <interface>
             <name>ICryptoFactory</name>
-            <instance>crypto</instance>
+            <instance>default</instance>
+            <instance>widevine</instance>
         </interface>
         <interface>
             <name>IDrmFactory</name>
-            <instance>drm</instance>
+            <instance>default</instance>
+            <instance>widevine</instance>
+        </interface>
+    </hal>
+    <hal format="hidl">
+        <name>android.hardware.soundtrigger</name>
+        <transport>hwbinder</transport>
+        <version>2.0</version>
+        <interface>
+            <name>ISoundTriggerHw</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl">
+        <name>android.hardware.audio.effect</name>
+        <transport>hwbinder</transport>
+        <version>2.0</version>
+        <interface>
+            <name>IEffectsFactory</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl">
+        <name>android.hardware.biometrics.fingerprint</name>
+        <transport>hwbinder</transport>
+        <version>2.1</version>
+        <interface>
+            <name>IBiometricsFingerprint</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl">
+        <name>android.hardware.configstore</name>
+        <transport>hwbinder</transport>
+        <version>1.0</version>
+        <interface>
+            <name>ISurfaceFlingerConfigs</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl">
+        <name>android.hardware.audio</name>
+        <transport>hwbinder</transport>
+        <version>2.0</version>
+        <interface>
+            <name>IDevicesFactory</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl">
+        <name>android.hardware.keymaster</name>
+        <transport>hwbinder</transport>
+        <version>3.0</version>
+        <interface>
+            <name>IKeymasterDevice</name>
+            <instance>default</instance>
         </interface>
     </hal>
     <hal format="hidl">
@@ -24,6 +78,24 @@
         </interface>
     </hal>
     <hal format="hidl">
+        <name>android.hardware.graphics.mapper</name>
+        <transport arch="32+64">passthrough</transport>
+        <version>2.0</version>
+        <interface>
+            <name>IMapper</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl">
+        <name>android.hardware.graphics.composer</name>
+        <transport>hwbinder</transport>
+        <version>2.1</version>
+        <interface>
+            <name>IComposer</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl">
         <name>android.hardware.power</name>
         <transport>hwbinder</transport>
         <version>1.0</version>
@@ -32,4 +104,83 @@
             <instance>default</instance>
         </interface>
     </hal>
+    <hal format="hidl">
+        <name>android.hardware.broadcastradio</name>
+        <transport>hwbinder</transport>
+        <version>1.0</version>
+        <interface>
+            <name>IBroadcastRadioFactory</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl">
+        <name>android.hardware.camera.provider</name>
+        <transport>hwbinder</transport>
+        <version>2.4</version>
+        <interface>
+            <name>ICameraProvider</name>
+            <instance>legacy/0</instance>
+        </interface>
+    </hal>
+    <hal format="hidl">
+        <name>android.hardware.sensors</name>
+        <transport>hwbinder</transport>
+        <version>1.0</version>
+        <interface>
+            <name>ISensors</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl">
+        <name>android.hardware.gatekeeper</name>
+        <transport>hwbinder</transport>
+        <version>1.0</version>
+        <interface>
+            <name>IGatekeeper</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl">
+        <name>android.hardware.gnss</name>
+        <transport>hwbinder</transport>
+        <version>1.0</version>
+        <interface>
+            <name>IGnss</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl">
+        <name>android.hardware.media.omx</name>
+        <transport>hwbinder</transport>
+        <version>1.0</version>
+        <interface>
+            <name>IOmx</name>
+            <instance>default</instance>
+        </interface>
+        <interface>
+            <name>IOmxStore</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl">
+        <name>android.hardware.radio.deprecated</name>
+        <transport>hwbinder</transport>
+        <version>1.0</version>
+        <interface>
+            <name>IOemHook</name>
+            <instance>slot1</instance>
+        </interface>
+    </hal>
+    <hal format="hidl">
+        <name>android.hardware.radio</name>
+        <transport>hwbinder</transport>
+        <version>1.0</version>
+        <interface>
+            <name>IRadio</name>
+            <instance>slot1</instance>
+        </interface>
+    </hal>
+    <sepolicy>
+        <version>10000.0</version>
+    </sepolicy>
 </manifest>
diff --git a/overlay/frameworks/base/core/res/res/values/config.xml b/overlay/frameworks/base/core/res/res/values/config.xml
index fb7c56f..e7923e4 100644
--- a/overlay/frameworks/base/core/res/res/values/config.xml
+++ b/overlay/frameworks/base/core/res/res/values/config.xml
@@ -30,4 +30,10 @@
     <!-- Set to true to add links to Cell Broadcast app from Settings and MMS app. -->
     <bool name="config_cellBroadcastAppLinks">true</bool>
 
+    <!-- MMS user agent string -->
+    <string name="config_mms_user_agent" translatable="false">GoldfishNexus</string>
+
+    <!-- MMS user agent prolfile url -->
+    <string name="config_mms_user_agent_profile_url" translatable="false">http://gsm.lge.com/html/gsm/Nexus5-M3.xml</string>
+
 </resources>
diff --git a/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml b/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml
index 56fbf89..6602627 100644
--- a/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml
+++ b/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml
@@ -18,9 +18,7 @@
 -->
 
 <resources>
-    <!-- cannot set this to true because O-CTS is testing the keyguard b/37465076
     <bool name="def_lockscreen_disabled">true</bool>
-    -->
 
     <!-- Allow users to use both the on-screen keyboard, as well as a real
          keyboard -->
diff --git a/overlay/packages/apps/CarrierConfig/res/xml/vendor.xml b/overlay/packages/apps/CarrierConfig/res/xml/vendor.xml
new file mode 100644
index 0000000..f5034ed
--- /dev/null
+++ b/overlay/packages/apps/CarrierConfig/res/xml/vendor.xml
@@ -0,0 +1,11 @@
+<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
+<!-- This is a place for vendor-specific config values. The format and
+     filtering rules are the same as those in carrier_config*.xml files. This
+     file is read after any specific config file from the assets folder, so it
+     must use explicit filters for MCC ad MNC if that is desired. -->
+
+<carrier_config_list>
+<carrier_config>
+<boolean name="enabledMMS" value="false"/>
+</carrier_config>
+</carrier_config_list>
diff --git a/power/Android.mk b/power/Android.mk
index 3839088..a4d4a2c 100644
--- a/power/Android.mk
+++ b/power/Android.mk
@@ -19,6 +19,7 @@
 # hw/<POWERS_HARDWARE_MODULE_ID>.<ro.hardware>.so
 include $(CLEAR_VARS)
 
+LOCAL_VENDOR_MODULE := true
 LOCAL_MODULE_RELATIVE_PATH := hw
 LOCAL_CFLAGS += -DQEMU_HARDWARE
 LOCAL_SHARED_LIBRARIES := liblog libcutils
@@ -30,6 +31,7 @@
 
 include $(CLEAR_VARS)
 
+LOCAL_VENDOR_MODULE := true
 LOCAL_MODULE_RELATIVE_PATH := hw
 LOCAL_CFLAGS += -DQEMU_HARDWARE
 LOCAL_SHARED_LIBRARIES := liblog libcutils
diff --git a/qemu-props/Android.mk b/qemu-props/Android.mk
index d2af64d..b1b14db 100644
--- a/qemu-props/Android.mk
+++ b/qemu-props/Android.mk
@@ -22,6 +22,7 @@
 # to setup various system properties sent by the emulator program.
 #
 include $(CLEAR_VARS)
+LOCAL_VENDOR_MODULE    := true
 LOCAL_MODULE    := qemu-props
 LOCAL_C_INCLUDES += $(LOCAL_PATH)/../include
 LOCAL_SRC_FILES := qemu-props.c
diff --git a/qemud/Android.mk b/qemud/Android.mk
deleted file mode 100644
index 30ee5eb..0000000
--- a/qemud/Android.mk
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright 2008 The Android Open Source Project
-
-# We're moving the emulator-specific platform libs to
-# development.git/tools/emulator/. The following test is to ensure
-# smooth builds even if the tree contains both versions.
-#
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-	qemud.c
-
-
-LOCAL_SHARED_LIBRARIES := \
-	libcutils liblog
-
-LOCAL_MODULE:= qemud
-
-include $(BUILD_EXECUTABLE)
diff --git a/qemud/qemud.c b/qemud/qemud.c
deleted file mode 100644
index 3d18893..0000000
--- a/qemud/qemud.c
+++ /dev/null
@@ -1,1720 +0,0 @@
-#include <stdint.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <termios.h>
-#include <unistd.h>
-#include <cutils/sockets.h>
-
-/*
- *  the qemud daemon program is only used within Android as a bridge
- *  between the emulator program and the emulated system. it really works as
- *  a simple stream multiplexer that works as follows:
- *
- *    - qemud is started by init following instructions in
- *      /system/etc/init.goldfish.rc (i.e. it is never started on real devices)
- *
- *    - qemud communicates with the emulator program through a single serial
- *      port, whose name is passed through a kernel boot parameter
- *      (e.g. android.qemud=ttyS1)
- *
- *    - qemud binds one unix local stream socket (/dev/socket/qemud, created
- *      by init through /system/etc/init.goldfish.rc).
- *
- *
- *      emulator <==serial==> qemud <---> /dev/socket/qemud <-+--> client1
- *                                                            |
- *                                                            +--> client2
- *
- *   - the special channel index 0 is used by the emulator and qemud only.
- *     other channel numbers correspond to clients. More specifically,
- *     connection are created like this:
- *
- *     * the client connects to /dev/socket/qemud
- *
- *     * the client sends the service name through the socket, as
- *            <service-name>
- *
- *     * qemud creates a "Client" object internally, assigns it an
- *       internal unique channel number > 0, then sends a connection
- *       initiation request to the emulator (i.e. through channel 0):
- *
- *           connect:<id>:<name>
- *
- *       where <name> is the service name, and <id> is a 2-hexchar
- *       number corresponding to the channel number.
- *
- *     * in case of success, the emulator responds through channel 0
- *       with:
- *
- *           ok:connect:<id>
- *
- *       after this, all messages between the client and the emulator
- *       are passed in pass-through mode.
- *
- *     * if the emulator refuses the service connection, it will
- *       send the following through channel 0:
- *
- *           ko:connect:<id>:reason-for-failure
- *
- *     * If the client closes the connection, qemud sends the following
- *       to the emulator:
- *
- *           disconnect:<id>
- *
- *       The same message is the opposite direction if the emulator
- *       chooses to close the connection.
- *
- *     * any command sent through channel 0 to the emulator that is
- *       not properly recognized will be answered by:
- *
- *           ko:unknown command
- *
- *
- *  Internally, the daemon maintains a "Client" object for each client
- *  connection (i.e. accepting socket connection).
- */
-
-/* name of the single control socket used by the daemon */
-#define CONTROL_SOCKET_NAME  "qemud"
-
-#define  DEBUG     0
-#define  T_ACTIVE  0  /* set to 1 to dump traffic */
-
-#if DEBUG
-#  define LOG_TAG  "qemud"
-#  include <cutils/log.h>
-#  define  D(...)   ALOGD(__VA_ARGS__)
-#else
-#  define  D(...)  ((void)0)
-#  define  T(...)  ((void)0)
-#endif
-
-#if T_ACTIVE
-#  define  T(...)   D(__VA_ARGS__)
-#else
-#  define  T(...)   ((void)0)
-#endif
-
-/** UTILITIES
- **/
-
-static void
-fatal( const char*  fmt, ... )
-{
-    va_list  args;
-    va_start(args, fmt);
-    fprintf(stderr, "PANIC: ");
-    vfprintf(stderr, fmt, args);
-    fprintf(stderr, "\n" );
-    va_end(args);
-    exit(1);
-}
-
-static void*
-xalloc( size_t   sz )
-{
-    void*  p;
-
-    if (sz == 0)
-        return NULL;
-
-    p = malloc(sz);
-    if (p == NULL)
-        fatal( "not enough memory" );
-
-    return p;
-}
-
-#define  xnew(p)   (p) = xalloc(sizeof(*(p)))
-
-static void*
-xalloc0( size_t  sz )
-{
-    void*  p = xalloc(sz);
-    memset( p, 0, sz );
-    return p;
-}
-
-#define  xnew0(p)   (p) = xalloc0(sizeof(*(p)))
-
-#define  xfree(p)    (free((p)), (p) = NULL)
-
-static void*
-xrealloc( void*  block, size_t  size )
-{
-    void*  p = realloc( block, size );
-
-    if (p == NULL && size > 0)
-        fatal( "not enough memory" );
-
-    return p;
-}
-
-#define  xrenew(p,count)  (p) = xrealloc((p),sizeof(*(p))*(count))
-
-static int
-hex2int( const uint8_t*  data, int  len )
-{
-    int  result = 0;
-    while (len > 0) {
-        int       c = *data++;
-        unsigned  d;
-
-        result <<= 4;
-        do {
-            d = (unsigned)(c - '0');
-            if (d < 10)
-                break;
-
-            d = (unsigned)(c - 'a');
-            if (d < 6) {
-                d += 10;
-                break;
-            }
-
-            d = (unsigned)(c - 'A');
-            if (d < 6) {
-                d += 10;
-                break;
-            }
-
-            return -1;
-        }
-        while (0);
-
-        result |= d;
-        len    -= 1;
-    }
-    return  result;
-}
-
-
-static void
-int2hex( int  value, uint8_t*  to, int  width )
-{
-    int  nn = 0;
-    static const char hexchars[16] = "0123456789abcdef";
-
-    for ( --width; width >= 0; width--, nn++ ) {
-        to[nn] = hexchars[(value >> (width*4)) & 15];
-    }
-}
-
-static int
-fd_read(int  fd, void*  to, int  len)
-{
-    int  ret;
-
-    do {
-        ret = read(fd, to, len);
-    } while (ret < 0 && errno == EINTR);
-
-    return ret;
-}
-
-static int
-fd_write(int  fd, const void*  from, int  len)
-{
-    int  ret;
-
-    do {
-        ret = write(fd, from, len);
-    } while (ret < 0 && errno == EINTR);
-
-    return ret;
-}
-
-static void
-fd_setnonblock(int  fd)
-{
-    int  ret, flags;
-
-    do {
-        flags = fcntl(fd, F_GETFD);
-    } while (flags < 0 && errno == EINTR);
-
-    if (flags < 0) {
-        fatal( "%s: could not get flags for fd %d: %s",
-               __FUNCTION__, fd, strerror(errno) );
-    }
-
-    do {
-        ret = fcntl(fd, F_SETFD, flags | O_NONBLOCK);
-    } while (ret < 0 && errno == EINTR);
-
-    if (ret < 0) {
-        fatal( "%s: could not set fd %d to non-blocking: %s",
-               __FUNCTION__, fd, strerror(errno) );
-    }
-}
-
-
-static int
-fd_accept(int  fd)
-{
-    struct sockaddr  from;
-    socklen_t        fromlen = sizeof(from);
-    int              ret;
-
-    do {
-        ret = accept(fd, &from, &fromlen);
-    } while (ret < 0 && errno == EINTR);
-
-    return ret;
-}
-
-/** FD EVENT LOOP
- **/
-
-/* A Looper object is used to monitor activity on one or more
- * file descriptors (e.g sockets).
- *
- * - call looper_add() to register a function that will be
- *   called when events happen on the file descriptor.
- *
- * - call looper_enable() or looper_disable() to enable/disable
- *   the set of monitored events for a given file descriptor.
- *
- * - call looper_del() to unregister a file descriptor.
- *   this does *not* close the file descriptor.
- *
- * Note that you can only provide a single function to handle
- * all events related to a given file descriptor.
-
- * You can call looper_enable/_disable/_del within a function
- * callback.
- */
-
-/* the current implementation uses Linux's epoll facility
- * the event mask we use are simply combinations of EPOLLIN
- * EPOLLOUT, EPOLLHUP and EPOLLERR
- */
-#include <sys/epoll.h>
-
-#define  MAX_CHANNELS  16
-#define  MAX_EVENTS    (MAX_CHANNELS+1)  /* each channel + the serial fd */
-
-/* the event handler function type, 'user' is a user-specific
- * opaque pointer passed to looper_add().
- */
-typedef void (*EventFunc)( void*  user, int  events );
-
-/* bit flags for the LoopHook structure.
- *
- * HOOK_PENDING means that an event happened on the
- * corresponding file descriptor.
- *
- * HOOK_CLOSING is used to delay-close monitored
- * file descriptors.
- */
-enum {
-    HOOK_PENDING = (1 << 0),
-    HOOK_CLOSING = (1 << 1),
-};
-
-/* A LoopHook structure is used to monitor a given
- * file descriptor and record its event handler.
- */
-typedef struct {
-    int        fd;
-    int        wanted;  /* events we are monitoring */
-    int        events;  /* events that occured */
-    int        state;   /* see HOOK_XXX constants */
-    void*      ev_user; /* user-provided handler parameter */
-    EventFunc  ev_func; /* event handler callback */
-} LoopHook;
-
-/* Looper is the main object modeling a looper object
- */
-typedef struct {
-    int                  epoll_fd;
-    int                  num_fds;
-    int                  max_fds;
-    struct epoll_event*  events;
-    LoopHook*            hooks;
-} Looper;
-
-/* initialize a looper object */
-static void
-looper_init( Looper*  l )
-{
-    l->epoll_fd = epoll_create(4);
-    l->num_fds  = 0;
-    l->max_fds  = 0;
-    l->events   = NULL;
-    l->hooks    = NULL;
-}
-
-/* finalize a looper object */
-static void
-looper_done( Looper*  l )
-{
-    xfree(l->events);
-    xfree(l->hooks);
-    l->max_fds = 0;
-    l->num_fds = 0;
-
-    close(l->epoll_fd);
-    l->epoll_fd  = -1;
-}
-
-/* return the LoopHook corresponding to a given
- * monitored file descriptor, or NULL if not found
- */
-static LoopHook*
-looper_find( Looper*  l, int  fd )
-{
-    LoopHook*  hook = l->hooks;
-    LoopHook*  end  = hook + l->num_fds;
-
-    for ( ; hook < end; hook++ ) {
-        if (hook->fd == fd)
-            return hook;
-    }
-    return NULL;
-}
-
-/* grow the arrays in the looper object */
-static void
-looper_grow( Looper*  l )
-{
-    int  old_max = l->max_fds;
-    int  new_max = old_max + (old_max >> 1) + 4;
-    int  n;
-
-    xrenew( l->events, new_max );
-    xrenew( l->hooks,  new_max );
-    l->max_fds = new_max;
-
-    /* now change the handles to all events */
-    for (n = 0; n < l->num_fds; n++) {
-        struct epoll_event ev;
-        LoopHook*          hook = l->hooks + n;
-
-        ev.events   = hook->wanted;
-        ev.data.ptr = hook;
-        epoll_ctl( l->epoll_fd, EPOLL_CTL_MOD, hook->fd, &ev );
-    }
-}
-
-/* register a file descriptor and its event handler.
- * no event mask will be enabled
- */
-static void
-looper_add( Looper*  l, int  fd, EventFunc  func, void*  user )
-{
-    struct epoll_event  ev;
-    LoopHook*           hook;
-
-    if (l->num_fds >= l->max_fds)
-        looper_grow(l);
-
-    hook = l->hooks + l->num_fds;
-
-    hook->fd      = fd;
-    hook->ev_user = user;
-    hook->ev_func = func;
-    hook->state   = 0;
-    hook->wanted  = 0;
-    hook->events  = 0;
-
-    fd_setnonblock(fd);
-
-    ev.events   = 0;
-    ev.data.ptr = hook;
-    epoll_ctl( l->epoll_fd, EPOLL_CTL_ADD, fd, &ev );
-
-    l->num_fds += 1;
-}
-
-/* unregister a file descriptor and its event handler
- */
-static void
-looper_del( Looper*  l, int  fd )
-{
-    LoopHook*  hook = looper_find( l, fd );
-
-    if (!hook) {
-        D( "%s: invalid fd: %d", __FUNCTION__, fd );
-        return;
-    }
-    /* don't remove the hook yet */
-    hook->state |= HOOK_CLOSING;
-
-    epoll_ctl( l->epoll_fd, EPOLL_CTL_DEL, fd, NULL );
-}
-
-/* enable monitoring of certain events for a file
- * descriptor. This adds 'events' to the current
- * event mask
- */
-static void
-looper_enable( Looper*  l, int  fd, int  events )
-{
-    LoopHook*  hook = looper_find( l, fd );
-
-    if (!hook) {
-        D("%s: invalid fd: %d", __FUNCTION__, fd );
-        return;
-    }
-
-    if (events & ~hook->wanted) {
-        struct epoll_event  ev;
-
-        hook->wanted |= events;
-        ev.events   = hook->wanted;
-        ev.data.ptr = hook;
-
-        epoll_ctl( l->epoll_fd, EPOLL_CTL_MOD, fd, &ev );
-    }
-}
-
-/* disable monitoring of certain events for a file
- * descriptor. This ignores events that are not
- * currently enabled.
- */
-static void
-looper_disable( Looper*  l, int  fd, int  events )
-{
-    LoopHook*  hook = looper_find( l, fd );
-
-    if (!hook) {
-        D("%s: invalid fd: %d", __FUNCTION__, fd );
-        return;
-    }
-
-    if (events & hook->wanted) {
-        struct epoll_event  ev;
-
-        hook->wanted &= ~events;
-        ev.events   = hook->wanted;
-        ev.data.ptr = hook;
-
-        epoll_ctl( l->epoll_fd, EPOLL_CTL_MOD, fd, &ev );
-    }
-}
-
-/* wait until an event occurs on one of the registered file
- * descriptors. Only returns in case of error !!
- */
-static void
-looper_loop( Looper*  l )
-{
-    for (;;) {
-        int  n, count;
-
-        do {
-            count = epoll_wait( l->epoll_fd, l->events, l->num_fds, -1 );
-        } while (count < 0 && errno == EINTR);
-
-        if (count < 0) {
-            D("%s: error: %s", __FUNCTION__, strerror(errno) );
-            return;
-        }
-
-        if (count == 0) {
-            D("%s: huh ? epoll returned count=0", __FUNCTION__);
-            continue;
-        }
-
-        /* mark all pending hooks */
-        for (n = 0; n < count; n++) {
-            LoopHook*  hook = l->events[n].data.ptr;
-            hook->state  = HOOK_PENDING;
-            hook->events = l->events[n].events;
-        }
-
-        /* execute hook callbacks. this may change the 'hooks'
-         * and 'events' array, as well as l->num_fds, so be careful */
-        for (n = 0; n < l->num_fds; n++) {
-            LoopHook*  hook = l->hooks + n;
-            if (hook->state & HOOK_PENDING) {
-                hook->state &= ~HOOK_PENDING;
-                hook->ev_func( hook->ev_user, hook->events );
-            }
-        }
-
-        /* now remove all the hooks that were closed by
-         * the callbacks */
-        for (n = 0; n < l->num_fds;) {
-            struct epoll_event ev;
-            LoopHook*  hook = l->hooks + n;
-
-            if (!(hook->state & HOOK_CLOSING)) {
-                n++;
-                continue;
-            }
-
-            hook[0]     = l->hooks[l->num_fds-1];
-            l->num_fds -= 1;
-            ev.events   = hook->wanted;
-            ev.data.ptr = hook;
-            epoll_ctl( l->epoll_fd, EPOLL_CTL_MOD, hook->fd, &ev );
-        }
-    }
-}
-
-#if T_ACTIVE
-char*
-quote( const void*  data, int  len )
-{
-    const char*  p   = data;
-    const char*  end = p + len;
-    int          count = 0;
-    int          phase = 0;
-    static char*  buff = NULL;
-
-    for (phase = 0; phase < 2; phase++) {
-        if (phase != 0) {
-            xfree(buff);
-            buff = xalloc(count+1);
-        }
-        count = 0;
-        for (p = data; p < end; p++) {
-            int  c = *p;
-
-            if (c == '\\') {
-                if (phase != 0) {
-                    buff[count] = buff[count+1] = '\\';
-                }
-                count += 2;
-                continue;
-            }
-
-            if (c >= 32 && c < 127) {
-                if (phase != 0)
-                    buff[count] = c;
-                count += 1;
-                continue;
-            }
-
-
-            if (c == '\t') {
-                if (phase != 0) {
-                    memcpy(buff+count, "<TAB>", 5);
-                }
-                count += 5;
-                continue;
-            }
-            if (c == '\n') {
-                if (phase != 0) {
-                    memcpy(buff+count, "<LN>", 4);
-                }
-                count += 4;
-                continue;
-            }
-            if (c == '\r') {
-                if (phase != 0) {
-                    memcpy(buff+count, "<CR>", 4);
-                }
-                count += 4;
-                continue;
-            }
-
-            if (phase != 0) {
-                buff[count+0] = '\\';
-                buff[count+1] = 'x';
-                buff[count+2] = "0123456789abcdef"[(c >> 4) & 15];
-                buff[count+3] = "0123456789abcdef"[     (c) & 15];
-            }
-            count += 4;
-        }
-    }
-    buff[count] = 0;
-    return buff;
-}
-#endif /* T_ACTIVE */
-
-/** PACKETS
- **
- ** We need a way to buffer data before it can be sent to the
- ** corresponding file descriptor. We use linked list of Packet
- ** objects to do this.
- **/
-
-typedef struct Packet   Packet;
-
-#define  MAX_PAYLOAD  4000
-
-struct Packet {
-    Packet*   next;
-    int       len;
-    int       channel;
-    uint8_t   data[ MAX_PAYLOAD ];
-};
-
-/* we expect to alloc/free a lot of packets during
- * operations so use a single linked list of free packets
- * to keep things speedy and simple.
- */
-static Packet*   _free_packets;
-
-/* Allocate a packet */
-static Packet*
-packet_alloc(void)
-{
-    Packet*  p = _free_packets;
-    if (p != NULL) {
-        _free_packets = p->next;
-    } else {
-        xnew(p);
-    }
-    p->next    = NULL;
-    p->len     = 0;
-    p->channel = -1;
-    return p;
-}
-
-/* Release a packet. This takes the address of a packet
- * pointer that will be set to NULL on exit (avoids
- * referencing dangling pointers in case of bugs)
- */
-static void
-packet_free( Packet*  *ppacket )
-{
-    Packet*  p = *ppacket;
-    if (p) {
-        p->next       = _free_packets;
-        _free_packets = p;
-        *ppacket = NULL;
-    }
-}
-
-/** PACKET RECEIVER
- **
- ** Simple abstraction for something that can receive a packet
- ** from a FDHandler (see below) or something else.
- **
- ** Send a packet to it with 'receiver_post'
- **
- ** Call 'receiver_close' to indicate that the corresponding
- ** packet source was closed.
- **/
-
-typedef void (*PostFunc) ( void*  user, Packet*  p );
-typedef void (*CloseFunc)( void*  user );
-
-typedef struct {
-    PostFunc   post;
-    CloseFunc  close;
-    void*      user;
-} Receiver;
-
-/* post a packet to a receiver. Note that this transfers
- * ownership of the packet to the receiver.
- */
-static __inline__ void
-receiver_post( Receiver*  r, Packet*  p )
-{
-    if (r->post)
-        r->post( r->user, p );
-    else
-        packet_free(&p);
-}
-
-/* tell a receiver the packet source was closed.
- * this will also prevent further posting to the
- * receiver.
- */
-static __inline__ void
-receiver_close( Receiver*  r )
-{
-    if (r->close) {
-        r->close( r->user );
-        r->close = NULL;
-    }
-    r->post  = NULL;
-}
-
-
-/** FD HANDLERS
- **
- ** these are smart listeners that send incoming packets to a receiver
- ** and can queue one or more outgoing packets and send them when
- ** possible to the FD.
- **
- ** note that we support clean shutdown of file descriptors,
- ** i.e. we try to send all outgoing packets before destroying
- ** the FDHandler.
- **/
-
-typedef struct FDHandler      FDHandler;
-typedef struct FDHandlerList  FDHandlerList;
-
-struct FDHandler {
-    int             fd;
-    FDHandlerList*  list;
-    char            closing;
-    Receiver        receiver[1];
-
-    /* queue of outgoing packets */
-    int             out_pos;
-    Packet*         out_first;
-    Packet**        out_ptail;
-
-    FDHandler*      next;
-    FDHandler**     pref;
-
-};
-
-struct FDHandlerList {
-    /* the looper that manages the fds */
-    Looper*      looper;
-
-    /* list of active FDHandler objects */
-    FDHandler*   active;
-
-    /* list of closing FDHandler objects.
-     * these are waiting to push their
-     * queued packets to the fd before
-     * freeing themselves.
-     */
-    FDHandler*   closing;
-
-};
-
-/* remove a FDHandler from its current list */
-static void
-fdhandler_remove( FDHandler*  f )
-{
-    f->pref[0] = f->next;
-    if (f->next)
-        f->next->pref = f->pref;
-}
-
-/* add a FDHandler to a given list */
-static void
-fdhandler_prepend( FDHandler*  f, FDHandler**  list )
-{
-    f->next = list[0];
-    f->pref = list;
-    list[0] = f;
-    if (f->next)
-        f->next->pref = &f->next;
-}
-
-/* initialize a FDHandler list */
-static void
-fdhandler_list_init( FDHandlerList*  list, Looper*  looper )
-{
-    list->looper  = looper;
-    list->active  = NULL;
-    list->closing = NULL;
-}
-
-
-/* close a FDHandler (and free it). Note that this will not
- * perform a graceful shutdown, i.e. all packets in the
- * outgoing queue will be immediately free.
- *
- * this *will* notify the receiver that the file descriptor
- * was closed.
- *
- * you should call fdhandler_shutdown() if you want to
- * notify the FDHandler that its packet source is closed.
- */
-static void
-fdhandler_close( FDHandler*  f )
-{
-    /* notify receiver */
-    receiver_close(f->receiver);
-
-    /* remove the handler from its list */
-    fdhandler_remove(f);
-
-    /* get rid of outgoing packet queue */
-    if (f->out_first != NULL) {
-        Packet*  p;
-        while ((p = f->out_first) != NULL) {
-            f->out_first = p->next;
-            packet_free(&p);
-        }
-    }
-
-    /* get rid of file descriptor */
-    if (f->fd >= 0) {
-        looper_del( f->list->looper, f->fd );
-        close(f->fd);
-        f->fd = -1;
-    }
-
-    f->list = NULL;
-    xfree(f);
-}
-
-/* Ask the FDHandler to cleanly shutdown the connection,
- * i.e. send any pending outgoing packets then auto-free
- * itself.
- */
-static void
-fdhandler_shutdown( FDHandler*  f )
-{
-    /* prevent later fdhandler_close() to
-     * call the receiver's close.
-     */
-    f->receiver->close = NULL;
-
-    if (f->out_first != NULL && !f->closing)
-    {
-        /* move the handler to the 'closing' list */
-        f->closing = 1;
-        fdhandler_remove(f);
-        fdhandler_prepend(f, &f->list->closing);
-        return;
-    }
-
-    fdhandler_close(f);
-}
-
-/* Enqueue a new packet that the FDHandler will
- * send through its file descriptor.
- */
-static void
-fdhandler_enqueue( FDHandler*  f, Packet*  p )
-{
-    Packet*  first = f->out_first;
-
-    p->next         = NULL;
-    f->out_ptail[0] = p;
-    f->out_ptail    = &p->next;
-
-    if (first == NULL) {
-        f->out_pos = 0;
-        looper_enable( f->list->looper, f->fd, EPOLLOUT );
-    }
-}
-
-
-/* FDHandler file descriptor event callback for read/write ops */
-static void
-fdhandler_event( FDHandler*  f, int  events )
-{
-   int  len;
-
-    /* in certain cases, it's possible to have both EPOLLIN and
-     * EPOLLHUP at the same time. This indicates that there is incoming
-     * data to read, but that the connection was nonetheless closed
-     * by the sender. Be sure to read the data before closing
-     * the receiver to avoid packet loss.
-     */
-
-    if (events & EPOLLIN) {
-        Packet*  p = packet_alloc();
-        int      len;
-
-        if ((len = fd_read(f->fd, p->data, MAX_PAYLOAD)) < 0) {
-            D("%s: can't recv: %s", __FUNCTION__, strerror(errno));
-            packet_free(&p);
-        } else if (len > 0) {
-            p->len     = len;
-            p->channel = -101;  /* special debug value, not used */
-            receiver_post( f->receiver, p );
-        }
-    }
-
-    if (events & (EPOLLHUP|EPOLLERR)) {
-        /* disconnection */
-        D("%s: disconnect on fd %d", __FUNCTION__, f->fd);
-        fdhandler_close(f);
-        return;
-    }
-
-    if (events & EPOLLOUT && f->out_first) {
-        Packet*  p = f->out_first;
-        int      avail, len;
-
-        avail = p->len - f->out_pos;
-        if ((len = fd_write(f->fd, p->data + f->out_pos, avail)) < 0) {
-            D("%s: can't send: %s", __FUNCTION__, strerror(errno));
-        } else {
-            f->out_pos += len;
-            if (f->out_pos >= p->len) {
-                f->out_pos   = 0;
-                f->out_first = p->next;
-                packet_free(&p);
-                if (f->out_first == NULL) {
-                    f->out_ptail = &f->out_first;
-                    looper_disable( f->list->looper, f->fd, EPOLLOUT );
-                }
-            }
-        }
-    }
-}
-
-
-/* Create a new FDHandler that monitors read/writes */
-static FDHandler*
-fdhandler_new( int             fd,
-               FDHandlerList*  list,
-               Receiver*       receiver )
-{
-    FDHandler*  f = xalloc0(sizeof(*f));
-
-    f->fd          = fd;
-    f->list        = list;
-    f->receiver[0] = receiver[0];
-    f->out_first   = NULL;
-    f->out_ptail   = &f->out_first;
-    f->out_pos     = 0;
-
-    fdhandler_prepend(f, &list->active);
-
-    looper_add( list->looper, fd, (EventFunc) fdhandler_event, f );
-    looper_enable( list->looper, fd, EPOLLIN );
-
-    return f;
-}
-
-
-/* event callback function to monitor accepts() on server sockets.
- * the convention used here is that the receiver will receive a
- * dummy packet with the new client socket in p->channel
- */
-static void
-fdhandler_accept_event( FDHandler*  f, int  events )
-{
-    if (events & EPOLLIN) {
-        /* this is an accept - send a dummy packet to the receiver */
-        Packet*  p = packet_alloc();
-
-        D("%s: accepting on fd %d", __FUNCTION__, f->fd);
-        p->data[0] = 1;
-        p->len     = 1;
-        p->channel = fd_accept(f->fd);
-        if (p->channel < 0) {
-            D("%s: accept failed ?: %s", __FUNCTION__, strerror(errno));
-            packet_free(&p);
-            return;
-        }
-        receiver_post( f->receiver, p );
-    }
-
-    if (events & (EPOLLHUP|EPOLLERR)) {
-        /* disconnecting !! */
-        D("%s: closing accept fd %d", __FUNCTION__, f->fd);
-        fdhandler_close(f);
-        return;
-    }
-}
-
-
-/* Create a new FDHandler used to monitor new connections on a
- * server socket. The receiver must expect the new connection
- * fd in the 'channel' field of a dummy packet.
- */
-static FDHandler*
-fdhandler_new_accept( int             fd,
-                      FDHandlerList*  list,
-                      Receiver*       receiver )
-{
-    FDHandler*  f = xalloc0(sizeof(*f));
-
-    f->fd          = fd;
-    f->list        = list;
-    f->receiver[0] = receiver[0];
-
-    fdhandler_prepend(f, &list->active);
-
-    looper_add( list->looper, fd, (EventFunc) fdhandler_accept_event, f );
-    looper_enable( list->looper, fd, EPOLLIN );
-    listen( fd, 5 );
-
-    return f;
-}
-
-/** SERIAL CONNECTION STATE
- **
- ** The following is used to handle the framing protocol
- ** used on the serial port connection.
- **/
-
-/* each packet is made of a 6 byte header followed by a payload
- * the header looks like:
- *
- *   offset   size    description
- *       0       2    a 2-byte hex string for the channel number
- *       4       4    a 4-char hex string for the size of the payload
- *       6       n    the payload itself
- */
-#define  HEADER_SIZE    6
-#define  CHANNEL_OFFSET 0
-#define  LENGTH_OFFSET  2
-#define  CHANNEL_SIZE   2
-#define  LENGTH_SIZE    4
-
-#define  CHANNEL_CONTROL  0
-
-/* The Serial object receives data from the serial port,
- * extracts the payload size and channel index, then sends
- * the resulting messages as a packet to a generic receiver.
- *
- * You can also use serial_send to send a packet through
- * the serial port.
- */
-typedef struct Serial {
-    FDHandler*  fdhandler;   /* used to monitor serial port fd */
-    Receiver    receiver[1]; /* send payload there */
-    int         in_len;      /* current bytes in input packet */
-    int         in_datalen;  /* payload size, or 0 when reading header */
-    int         in_channel;  /* extracted channel number */
-    Packet*     in_packet;   /* used to read incoming packets */
-} Serial;
-
-
-/* a callback called when the serial port's fd is closed */
-static void
-serial_fd_close( Serial*  s )
-{
-    fatal("unexpected serial port close !!");
-}
-
-static void
-serial_dump( Packet*  p, const char*  funcname )
-{
-    T("%s: %03d bytes: '%s'",
-      funcname, p->len, quote(p->data, p->len));
-}
-
-/* a callback called when a packet arrives from the serial port's FDHandler.
- *
- * This will essentially parse the header, extract the channel number and
- * the payload size and store them in 'in_datalen' and 'in_channel'.
- *
- * After that, the payload is sent to the receiver once completed.
- */
-static void
-serial_fd_receive( Serial*  s, Packet*  p )
-{
-    int      rpos  = 0, rcount = p->len;
-    Packet*  inp   = s->in_packet;
-    int      inpos = s->in_len;
-
-    serial_dump( p, __FUNCTION__ );
-
-    while (rpos < rcount)
-    {
-        int  avail = rcount - rpos;
-
-        /* first, try to read the header */
-        if (s->in_datalen == 0) {
-            int  wanted = HEADER_SIZE - inpos;
-            if (avail > wanted)
-                avail = wanted;
-
-            memcpy( inp->data + inpos, p->data + rpos, avail );
-            inpos += avail;
-            rpos  += avail;
-
-            if (inpos == HEADER_SIZE) {
-                s->in_datalen = hex2int( inp->data + LENGTH_OFFSET,  LENGTH_SIZE );
-                s->in_channel = hex2int( inp->data + CHANNEL_OFFSET, CHANNEL_SIZE );
-
-                if (s->in_datalen <= 0) {
-                    D("ignoring %s packet from serial port",
-                      s->in_datalen ? "empty" : "malformed");
-                    s->in_datalen = 0;
-                }
-
-                //D("received %d bytes packet for channel %d", s->in_datalen, s->in_channel);
-                inpos = 0;
-            }
-        }
-        else /* then, populate the packet itself */
-        {
-            int   wanted = s->in_datalen - inpos;
-
-            if (avail > wanted)
-                avail = wanted;
-
-            memcpy( inp->data + inpos, p->data + rpos, avail );
-            inpos += avail;
-            rpos  += avail;
-
-            if (inpos == s->in_datalen) {
-                if (s->in_channel < 0) {
-                    D("ignoring %d bytes addressed to channel %d",
-                       inpos, s->in_channel);
-                } else {
-                    inp->len     = inpos;
-                    inp->channel = s->in_channel;
-                    receiver_post( s->receiver, inp );
-                    s->in_packet  = inp = packet_alloc();
-                }
-                s->in_datalen = 0;
-                inpos         = 0;
-            }
-        }
-    }
-    s->in_len = inpos;
-    packet_free(&p);
-}
-
-
-/* send a packet to the serial port.
- * this assumes that p->len and p->channel contain the payload's
- * size and channel and will add the appropriate header.
- */
-static void
-serial_send( Serial*  s, Packet*  p )
-{
-    Packet*  h = packet_alloc();
-
-    //D("sending to serial %d bytes from channel %d: '%.*s'", p->len, p->channel, p->len, p->data);
-
-    /* insert a small header before this packet */
-    h->len = HEADER_SIZE;
-    int2hex( p->len,     h->data + LENGTH_OFFSET,  LENGTH_SIZE );
-    int2hex( p->channel, h->data + CHANNEL_OFFSET, CHANNEL_SIZE );
-
-    serial_dump( h, __FUNCTION__ );
-    serial_dump( p, __FUNCTION__ );
-
-    fdhandler_enqueue( s->fdhandler, h );
-    fdhandler_enqueue( s->fdhandler, p );
-}
-
-
-/* initialize serial reader */
-static void
-serial_init( Serial*         s,
-             int             fd,
-             FDHandlerList*  list,
-             Receiver*       receiver )
-{
-    Receiver  recv;
-
-    recv.user  = s;
-    recv.post  = (PostFunc)  serial_fd_receive;
-    recv.close = (CloseFunc) serial_fd_close;
-
-    s->receiver[0] = receiver[0];
-
-    s->fdhandler = fdhandler_new( fd, list, &recv );
-    s->in_len     = 0;
-    s->in_datalen = 0;
-    s->in_channel = 0;
-    s->in_packet  = packet_alloc();
-}
-
-
-/** CLIENTS
- **/
-
-typedef struct Client       Client;
-typedef struct Multiplexer  Multiplexer;
-
-/* A Client object models a single qemud client socket
- * connection in the emulated system.
- *
- * the client first sends the name of the system service
- * it wants to contact (no framing), then waits for a 2
- * byte answer from qemud.
- *
- * the answer is either "OK" or "KO" to indicate
- * success or failure.
- *
- * In case of success, the client can send messages
- * to the service.
- *
- * In case of failure, it can disconnect or try sending
- * the name of another service.
- */
-struct Client {
-    Client*       next;
-    Client**      pref;
-    int           channel;
-    char          registered;
-    FDHandler*    fdhandler;
-    Multiplexer*  multiplexer;
-};
-
-struct Multiplexer {
-    Client*        clients;
-    int            last_channel;
-    Serial         serial[1];
-    Looper         looper[1];
-    FDHandlerList  fdhandlers[1];
-};
-
-
-static int   multiplexer_open_channel( Multiplexer*  mult, Packet*  p );
-static void  multiplexer_close_channel( Multiplexer*  mult, int  channel );
-static void  multiplexer_serial_send( Multiplexer* mult, int  channel, Packet*  p );
-
-static void
-client_dump( Client*  c, Packet*  p, const char*  funcname )
-{
-    T("%s: client %p (%d): %3d bytes: '%s'",
-      funcname, c, c->fdhandler->fd,
-      p->len, quote(p->data, p->len));
-}
-
-/* destroy a client */
-static void
-client_free( Client*  c )
-{
-    /* remove from list */
-    c->pref[0] = c->next;
-    if (c->next)
-        c->next->pref = c->pref;
-
-    c->channel    = -1;
-    c->registered = 0;
-
-    /* gently ask the FDHandler to shutdown to
-     * avoid losing queued outgoing packets */
-    if (c->fdhandler != NULL) {
-        fdhandler_shutdown(c->fdhandler);
-        c->fdhandler = NULL;
-    }
-
-    xfree(c);
-}
-
-
-/* a function called when a client socket receives data */
-static void
-client_fd_receive( Client*  c, Packet*  p )
-{
-    client_dump(c, p, __FUNCTION__);
-
-    if (c->registered) {
-        /* the client is registered, just send the
-         * data through the serial port
-         */
-        multiplexer_serial_send(c->multiplexer, c->channel, p);
-        return;
-    }
-
-    if (c->channel > 0) {
-        /* the client is waiting registration results.
-         * this should not happen because the client
-         * should wait for our 'ok' or 'ko'.
-         * close the connection.
-         */
-         D("%s: bad client sending data before end of registration",
-           __FUNCTION__);
-     BAD_CLIENT:
-         packet_free(&p);
-         client_free(c);
-         return;
-    }
-
-    /* the client hasn't registered a service yet,
-     * so this must be the name of a service, call
-     * the multiplexer to start registration for
-     * it.
-     */
-    D("%s: attempting registration for service '%.*s'",
-      __FUNCTION__, p->len, p->data);
-    c->channel = multiplexer_open_channel(c->multiplexer, p);
-    if (c->channel < 0) {
-        D("%s: service name too long", __FUNCTION__);
-        goto BAD_CLIENT;
-    }
-    D("%s:    -> received channel id %d", __FUNCTION__, c->channel);
-    packet_free(&p);
-}
-
-
-/* a function called when the client socket is closed. */
-static void
-client_fd_close( Client*  c )
-{
-    T("%s: client %p (%d)", __FUNCTION__, c, c->fdhandler->fd);
-
-    /* no need to shutdown the FDHandler */
-    c->fdhandler = NULL;
-
-    /* tell the emulator we're out */
-    if (c->channel > 0)
-        multiplexer_close_channel(c->multiplexer, c->channel);
-
-    /* free the client */
-    client_free(c);
-}
-
-/* a function called when the multiplexer received a registration
- * response from the emulator for a given client.
- */
-static void
-client_registration( Client*  c, int  registered )
-{
-    Packet*  p = packet_alloc();
-
-    /* sends registration status to client */
-    if (!registered) {
-        D("%s: registration failed for client %d", __FUNCTION__, c->channel);
-        memcpy( p->data, "KO", 2 );
-        p->len = 2;
-    } else {
-        D("%s: registration succeeded for client %d", __FUNCTION__, c->channel);
-        memcpy( p->data, "OK", 2 );
-        p->len = 2;
-    }
-    client_dump(c, p, __FUNCTION__);
-    fdhandler_enqueue(c->fdhandler, p);
-
-    /* now save registration state
-     */
-    c->registered = registered;
-    if (!registered) {
-        /* allow the client to try registering another service */
-        c->channel = -1;
-    }
-}
-
-/* send data to a client */
-static void
-client_send( Client*  c, Packet*  p )
-{
-    client_dump(c, p, __FUNCTION__);
-    fdhandler_enqueue(c->fdhandler, p);
-}
-
-
-/* Create new client socket handler */
-static Client*
-client_new( Multiplexer*    mult,
-            int             fd,
-            FDHandlerList*  pfdhandlers,
-            Client**        pclients )
-{
-    Client*   c;
-    Receiver  recv;
-
-    xnew(c);
-
-    c->multiplexer = mult;
-    c->next        = NULL;
-    c->pref        = &c->next;
-    c->channel     = -1;
-    c->registered  = 0;
-
-    recv.user  = c;
-    recv.post  = (PostFunc)  client_fd_receive;
-    recv.close = (CloseFunc) client_fd_close;
-
-    c->fdhandler = fdhandler_new( fd, pfdhandlers, &recv );
-
-    /* add to client list */
-    c->next   = *pclients;
-    c->pref   = pclients;
-    *pclients = c;
-    if (c->next)
-        c->next->pref = &c->next;
-
-    return c;
-}
-
-/**  GLOBAL MULTIPLEXER
- **/
-
-/* find a client by its channel */
-static Client*
-multiplexer_find_client( Multiplexer*  mult, int  channel )
-{
-    Client* c = mult->clients;
-
-    for ( ; c != NULL; c = c->next ) {
-        if (c->channel == channel)
-            return c;
-    }
-    return NULL;
-}
-
-/* handle control messages coming from the serial port
- * on CONTROL_CHANNEL.
- */
-static void
-multiplexer_handle_control( Multiplexer*  mult, Packet*  p )
-{
-    /* connection registration success */
-    if (p->len == 13 && !memcmp(p->data, "ok:connect:", 11)) {
-        int      channel = hex2int(p->data+11, 2);
-        Client*  client  = multiplexer_find_client(mult, channel);
-
-        /* note that 'client' can be NULL if the corresponding
-         * socket was closed before the emulator response arrived.
-         */
-        if (client != NULL) {
-            client_registration(client, 1);
-        } else {
-            D("%s: NULL client: '%.*s'", __FUNCTION__, p->len, p->data+11);
-        }
-        goto EXIT;
-    }
-
-    /* connection registration failure */
-    if (p->len == 13 && !memcmp(p->data, "ko:connect:",11)) {
-        int     channel = hex2int(p->data+11, 2);
-        Client* client  = multiplexer_find_client(mult, channel);
-
-        if (client != NULL)
-            client_registration(client, 0);
-
-        goto EXIT;
-    }
-
-    /* emulator-induced client disconnection */
-    if (p->len == 13 && !memcmp(p->data, "disconnect:",11)) {
-        int      channel = hex2int(p->data+11, 2);
-        Client*  client  = multiplexer_find_client(mult, channel);
-
-        if (client != NULL)
-            client_free(client);
-
-        goto EXIT;
-    }
-
-    /* A message that begins with "X00" is a probe sent by
-     * the emulator used to detect which version of qemud it runs
-     * against (in order to detect 1.0/1.1 system images. Just
-     * silently ignore it there instead of printing an error
-     * message.
-     */
-    if (p->len >= 3 && !memcmp(p->data,"X00",3)) {
-        goto EXIT;
-    }
-
-    D("%s: unknown control message (%d bytes): '%.*s'",
-      __FUNCTION__, p->len, p->len, p->data);
-
-EXIT:
-    packet_free(&p);
-}
-
-/* a function called when an incoming packet comes from the serial port */
-static void
-multiplexer_serial_receive( Multiplexer*  mult, Packet*  p )
-{
-    Client*  client;
-
-    T("%s: channel=%d '%.*s'", __FUNCTION__, p->channel, p->len, p->data);
-
-    if (p->channel == CHANNEL_CONTROL) {
-        multiplexer_handle_control(mult, p);
-        return;
-    }
-
-    client = multiplexer_find_client(mult, p->channel);
-    if (client != NULL) {
-        client_send(client, p);
-        return;
-    }
-
-    D("%s: discarding packet for unknown channel %d", __FUNCTION__, p->channel);
-    packet_free(&p);
-}
-
-/* a function called when the serial reader closes */
-static void
-multiplexer_serial_close( Multiplexer*  mult )
-{
-    fatal("unexpected close of serial reader");
-}
-
-/* a function called to send a packet to the serial port */
-static void
-multiplexer_serial_send( Multiplexer*  mult, int  channel, Packet*  p )
-{
-    p->channel = channel;
-    serial_send( mult->serial, p );
-}
-
-
-
-/* a function used by a client to allocate a new channel id and
- * ask the emulator to open it. 'service' must be a packet containing
- * the name of the service in its payload.
- *
- * returns -1 if the service name is too long.
- *
- * notice that client_registration() will be called later when
- * the answer arrives.
- */
-static int
-multiplexer_open_channel( Multiplexer*  mult, Packet*  service )
-{
-    Packet*   p = packet_alloc();
-    int       len, channel;
-
-    /* find a free channel number, assume we don't have many
-     * clients here. */
-    {
-        Client*  c;
-    TRY_AGAIN:
-        channel = (++mult->last_channel) & 0xff;
-
-        for (c = mult->clients; c != NULL; c = c->next)
-            if (c->channel == channel)
-                goto TRY_AGAIN;
-    }
-
-    len = snprintf((char*)p->data, sizeof p->data, "connect:%.*s:%02x", service->len, service->data, channel);
-    if (len >= (int)sizeof(p->data)) {
-        D("%s: weird, service name too long (%d > %d)", __FUNCTION__, len, sizeof(p->data));
-        packet_free(&p);
-        return -1;
-    }
-    p->channel = CHANNEL_CONTROL;
-    p->len     = len;
-
-    serial_send(mult->serial, p);
-    return channel;
-}
-
-/* used to tell the emulator a channel was closed by a client */
-static void
-multiplexer_close_channel( Multiplexer*  mult, int  channel )
-{
-    Packet*  p   = packet_alloc();
-    int      len = snprintf((char*)p->data, sizeof(p->data), "disconnect:%02x", channel);
-
-    if (len > (int)sizeof(p->data)) {
-        /* should not happen */
-        return;
-    }
-
-    p->channel = CHANNEL_CONTROL;
-    p->len     = len;
-
-    serial_send(mult->serial, p);
-}
-
-/* this function is used when a new connection happens on the control
- * socket.
- */
-static void
-multiplexer_control_accept( Multiplexer*  m, Packet*  p )
-{
-    /* the file descriptor for the new socket connection is
-     * in p->channel. See fdhandler_accept_event() */
-    int      fd     = p->channel;
-    Client*  client = client_new( m, fd, m->fdhandlers, &m->clients );
-
-    D("created client %p listening on fd %d", client, fd);
-
-    /* free dummy packet */
-    packet_free(&p);
-}
-
-static void
-multiplexer_control_close( Multiplexer*  m )
-{
-    fatal("unexpected multiplexer control close");
-}
-
-static void
-multiplexer_init( Multiplexer*  m, const char*  serial_dev )
-{
-    int       fd, control_fd;
-    Receiver  recv;
-
-    /* initialize looper and fdhandlers list */
-    looper_init( m->looper );
-    fdhandler_list_init( m->fdhandlers, m->looper );
-
-    /* open the serial port */
-    do {
-        fd = open(serial_dev, O_RDWR);
-    } while (fd < 0 && errno == EINTR);
-
-    if (fd < 0) {
-        fatal( "%s: could not open '%s': %s", __FUNCTION__, serial_dev,
-               strerror(errno) );
-    }
-    // disable echo on serial lines
-    if ( !memcmp( serial_dev, "/dev/tty", 8 ) ) {
-        struct termios  ios;
-        tcgetattr( fd, &ios );
-        ios.c_lflag = 0;  /* disable ECHO, ICANON, etc... */
-        tcsetattr( fd, TCSANOW, &ios );
-    }
-
-    /* initialize the serial reader/writer */
-    recv.user  = m;
-    recv.post  = (PostFunc)  multiplexer_serial_receive;
-    recv.close = (CloseFunc) multiplexer_serial_close;
-
-    serial_init( m->serial, fd, m->fdhandlers, &recv );
-
-    /* open the qemud control socket */
-    recv.user  = m;
-    recv.post  = (PostFunc)  multiplexer_control_accept;
-    recv.close = (CloseFunc) multiplexer_control_close;
-
-    fd = android_get_control_socket(CONTROL_SOCKET_NAME);
-    if (fd < 0) {
-        fatal("couldn't get fd for control socket '%s'", CONTROL_SOCKET_NAME);
-    }
-
-    fdhandler_new_accept( fd, m->fdhandlers, &recv );
-
-    /* initialize clients list */
-    m->clients = NULL;
-}
-
-/** MAIN LOOP
- **/
-
-static Multiplexer  _multiplexer[1];
-
-int  main( void )
-{
-    Multiplexer*  m = _multiplexer;
-
-   /* extract the name of our serial device from the kernel
-    * boot options that are stored in /proc/cmdline
-    */
-#define  KERNEL_OPTION  "android.qemud="
-
-    {
-        char          buff[1024];
-        int           fd, len;
-        char*         p;
-        char*         q;
-
-        fd = open( "/proc/cmdline", O_RDONLY );
-        if (fd < 0) {
-            D("%s: can't open /proc/cmdline !!: %s", __FUNCTION__,
-            strerror(errno));
-            exit(1);
-        }
-
-        len = fd_read( fd, buff, sizeof(buff)-1 );
-        close(fd);
-        if (len < 0) {
-            D("%s: can't read /proc/cmdline: %s", __FUNCTION__,
-            strerror(errno));
-            exit(1);
-        }
-        buff[len] = 0;
-
-        p = strstr( buff, KERNEL_OPTION );
-        if (p == NULL) {
-            D("%s: can't find '%s' in /proc/cmdline",
-            __FUNCTION__, KERNEL_OPTION );
-            exit(1);
-        }
-
-        p += sizeof(KERNEL_OPTION)-1;  /* skip option */
-        q  = p;
-        while ( *q && *q != ' ' && *q != '\t' )
-            q += 1;
-
-        snprintf( buff, sizeof(buff), "/dev/%.*s", q-p, p );
-
-        multiplexer_init( m, buff );
-    }
-
-    D( "entering main loop");
-    looper_loop( m->looper );
-    D( "unexpected termination !!" );
-    return 0;
-}
diff --git a/sensors/Android.mk b/sensors/Android.mk
index e3df473..7a57bec 100644
--- a/sensors/Android.mk
+++ b/sensors/Android.mk
@@ -17,23 +17,9 @@
 
 # HAL module implemenation stored in
 # hw/<SENSORS_HARDWARE_MODULE_ID>.<ro.hardware>.so
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_SHARED_LIBRARIES := liblog libcutils
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/../include
-LOCAL_SRC_FILES := sensors_qemu.c
-ifeq ($(TARGET_PRODUCT),vbox_x86)
-LOCAL_MODULE := sensors.vbox_x86
-else
-LOCAL_MODULE := sensors.goldfish
-endif
-include $(BUILD_SHARED_LIBRARY)
-
-
 
 include $(CLEAR_VARS)
-
+LOCAL_VENDOR_MODULE := true
 LOCAL_MODULE_RELATIVE_PATH := hw
 LOCAL_SHARED_LIBRARIES := liblog libcutils
 LOCAL_C_INCLUDES += $(LOCAL_PATH)/../include
diff --git a/sensors/sensors_qemu.c b/sensors/sensors_qemu.c
index 9eee746..7954cf5 100644
--- a/sensors/sensors_qemu.c
+++ b/sensors/sensors_qemu.c
@@ -50,40 +50,46 @@
 /** SENSOR IDS AND NAMES
  **/
 
-#define MAX_NUM_SENSORS 8
+#define MAX_NUM_SENSORS 10
 
 #define SUPPORTED_SENSORS  ((1<<MAX_NUM_SENSORS)-1)
 
-#define  ID_BASE           SENSORS_HANDLE_BASE
-#define  ID_ACCELERATION   (ID_BASE+0)
-#define  ID_MAGNETIC_FIELD (ID_BASE+1)
-#define  ID_ORIENTATION    (ID_BASE+2)
-#define  ID_TEMPERATURE    (ID_BASE+3)
-#define  ID_PROXIMITY      (ID_BASE+4)
-#define  ID_LIGHT          (ID_BASE+5)
-#define  ID_PRESSURE       (ID_BASE+6)
-#define  ID_HUMIDITY       (ID_BASE+7)
+#define  ID_BASE                        SENSORS_HANDLE_BASE
+#define  ID_ACCELERATION                (ID_BASE+0)
+#define  ID_GYROSCOPE                   (ID_BASE+1)
+#define  ID_MAGNETIC_FIELD              (ID_BASE+2)
+#define  ID_ORIENTATION                 (ID_BASE+3)
+#define  ID_TEMPERATURE                 (ID_BASE+4)
+#define  ID_PROXIMITY                   (ID_BASE+5)
+#define  ID_LIGHT                       (ID_BASE+6)
+#define  ID_PRESSURE                    (ID_BASE+7)
+#define  ID_HUMIDITY                    (ID_BASE+8)
+#define  ID_MAGNETIC_FIELD_UNCALIBRATED (ID_BASE+9)
 
-#define  SENSORS_ACCELERATION    (1 << ID_ACCELERATION)
-#define  SENSORS_MAGNETIC_FIELD  (1 << ID_MAGNETIC_FIELD)
-#define  SENSORS_ORIENTATION     (1 << ID_ORIENTATION)
-#define  SENSORS_TEMPERATURE     (1 << ID_TEMPERATURE)
-#define  SENSORS_PROXIMITY       (1 << ID_PROXIMITY)
-#define  SENSORS_LIGHT           (1 << ID_LIGHT)
-#define  SENSORS_PRESSURE        (1 << ID_PRESSURE)
-#define  SENSORS_HUMIDITY        (1 << ID_HUMIDITY)
+#define  SENSORS_ACCELERATION                 (1 << ID_ACCELERATION)
+#define  SENSORS_GYROSCOPE                    (1 << ID_GYROSCOPE)
+#define  SENSORS_MAGNETIC_FIELD               (1 << ID_MAGNETIC_FIELD)
+#define  SENSORS_ORIENTATION                  (1 << ID_ORIENTATION)
+#define  SENSORS_TEMPERATURE                  (1 << ID_TEMPERATURE)
+#define  SENSORS_PROXIMITY                    (1 << ID_PROXIMITY)
+#define  SENSORS_LIGHT                        (1 << ID_LIGHT)
+#define  SENSORS_PRESSURE                     (1 << ID_PRESSURE)
+#define  SENSORS_HUMIDITY                     (1 << ID_HUMIDITY)
+#define  SENSORS_MAGNETIC_FIELD_UNCALIBRATED  (1 << ID_MAGNETIC_FIELD)
 
 #define  ID_CHECK(x)  ((unsigned)((x) - ID_BASE) < MAX_NUM_SENSORS)
 
 #define  SENSORS_LIST  \
     SENSOR_(ACCELERATION,"acceleration") \
+    SENSOR_(GYROSCOPE,"gyroscope") \
     SENSOR_(MAGNETIC_FIELD,"magnetic-field") \
     SENSOR_(ORIENTATION,"orientation") \
     SENSOR_(TEMPERATURE,"temperature") \
     SENSOR_(PROXIMITY,"proximity") \
     SENSOR_(LIGHT, "light") \
     SENSOR_(PRESSURE, "pressure") \
-    SENSOR_(HUMIDITY, "humidity")
+    SENSOR_(HUMIDITY, "humidity") \
+    SENSOR_(MAGNETIC_FIELD_UNCALIBRATED,"magnetic-field-uncalibrated") \
 
 static const struct {
     const char*  name;
@@ -317,6 +323,18 @@
             continue;
         }
 
+        /* "gyroscope:<x>:<y>:<z>" corresponds to a gyroscope event */
+        if (sscanf(buff, "gyroscope:%g:%g:%g", params+0, params+1, params+2)
+                == 3) {
+            new_sensors |= SENSORS_GYROSCOPE;
+            if (events[ID_GYROSCOPE].type == SENSOR_TYPE_META_DATA) continue;
+            events[ID_GYROSCOPE].gyro.x = params[0];
+            events[ID_GYROSCOPE].gyro.y = params[1];
+            events[ID_GYROSCOPE].gyro.z = params[2];
+            events[ID_GYROSCOPE].type = SENSOR_TYPE_GYROSCOPE;
+            continue;
+        }
+
         /* "orientation:<azimuth>:<pitch>:<roll>" is sent when orientation
          * changes */
         if (sscanf(buff, "orientation:%g:%g:%g", params+0, params+1, params+2)
@@ -347,6 +365,19 @@
             continue;
         }
 
+        if (sscanf(buff, "magnetic-uncalibrated:%g:%g:%g", params+0, params+1, params+2)
+                == 3) {
+            new_sensors |= SENSORS_MAGNETIC_FIELD_UNCALIBRATED;
+            if (events[ID_MAGNETIC_FIELD_UNCALIBRATED].type == SENSOR_TYPE_META_DATA) continue;
+            events[ID_MAGNETIC_FIELD_UNCALIBRATED].magnetic.x = params[0];
+            events[ID_MAGNETIC_FIELD_UNCALIBRATED].magnetic.y = params[1];
+            events[ID_MAGNETIC_FIELD_UNCALIBRATED].magnetic.z = params[2];
+            events[ID_MAGNETIC_FIELD_UNCALIBRATED].magnetic.status =
+                    SENSOR_STATUS_ACCURACY_HIGH;
+            events[ID_MAGNETIC_FIELD_UNCALIBRATED].type = SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED;
+            continue;
+        }
+
         /* "temperature:<celsius>" */
         if (sscanf(buff, "temperature:%g", params+0) == 1) {
             new_sensors |= SENSORS_TEMPERATURE;
@@ -656,6 +687,19 @@
           .reserved   = {}
         },
 
+        { .name       = "Goldfish 3-axis Gyroscope",
+          .vendor     = "The Android Open Source Project",
+          .version    = 1,
+          .handle     = ID_GYROSCOPE,
+          .type       = SENSOR_TYPE_GYROSCOPE,
+          .maxRange   = 11.1111111,
+          .resolution = 1.0f/1000.0f,
+          .power      = 3.0f,
+          .minDelay   = 10000,
+          .maxDelay   = 60 * 1000 * 1000,
+          .reserved   = {}
+        },
+
         { .name       = "Goldfish 3-axis Magnetic field sensor",
           .vendor     = "The Android Open Source Project",
           .version    = 1,
@@ -780,7 +824,20 @@
           .requiredPermission = 0,
           .flags = SENSOR_FLAG_CONTINUOUS_MODE,
           .reserved   = {}
-        }
+        },
+
+        { .name       = "Goldfish 3-axis Magnetic field sensor (uncalibrated)",
+          .vendor     = "The Android Open Source Project",
+          .version    = 1,
+          .handle     = ID_MAGNETIC_FIELD_UNCALIBRATED,
+          .type       = SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED,
+          .maxRange   = 2000.0f,
+          .resolution = 1.0f,
+          .power      = 6.7f,
+          .minDelay   = 10000,
+          .maxDelay   = 60 * 1000 * 1000,
+          .reserved   = {}
+        },
 };
 
 static struct sensor_t  sSensorList[MAX_NUM_SENSORS];
diff --git a/vndk/Android.mk b/vndk/Android.mk
new file mode 100644
index 0000000..a58aac5
--- /dev/null
+++ b/vndk/Android.mk
@@ -0,0 +1,58 @@
+ifneq ($(filter generic_x86 generic_x86_64 generic generic_arm64 generic_mips generic_mips64, $(TARGET_DEVICE)),)
+
+LOCAL_PATH := $(call my-dir)
+
+VNDK_SP_LIBRARIES := \
+    android.hardware.renderscript@1.0\
+    android.hardware.graphics.allocator@2.0\
+    android.hardware.graphics.mapper@2.0\
+    android.hardware.graphics.common@1.0\
+    libhwbinder\
+    libbase\
+    libcutils\
+    libhardware\
+    libhidlbase\
+    libhidltransport\
+    libutils\
+    libc++\
+    libRS_internal\
+    libRSDriver\
+    libRSCpuRef\
+    libbcinfo\
+    libblas\
+    libft2\
+    libpng\
+    libcompiler_rt\
+    libbacktrace\
+    libunwind\
+    libunwindstack\
+    liblzma\
+
+define add-vndk-sp-lib
+include $$(CLEAR_VARS)
+LOCAL_MODULE := $1.vndk-sp
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+LOCAL_PREBUILT_MODULE_FILE := $$(TARGET_OUT)/lib/$1.so
+LOCAL_MULTILIB := 32
+LOCAL_MODULE_TAGS := optional
+LOCAL_INSTALLED_MODULE_STEM := $1.so
+LOCAL_MODULE_SUFFIX := .so
+LOCAL_MODULE_RELATIVE_PATH := vndk-sp
+include $$(BUILD_PREBUILT)
+
+include $$(CLEAR_VARS)
+LOCAL_MODULE := $1.vndk-sp
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+LOCAL_PREBUILT_MODULE_FILE := $$(TARGET_OUT)/lib64/$1.so
+LOCAL_MULTILIB := 64
+LOCAL_MODULE_TAGS := optional
+LOCAL_INSTALLED_MODULE_STEM := $1.so
+LOCAL_MODULE_SUFFIX := .so
+LOCAL_MODULE_RELATIVE_PATH := vndk-sp
+include $$(BUILD_PREBUILT)
+endef
+
+$(foreach lib,$(VNDK_SP_LIBRARIES),\
+    $(eval $(call add-vndk-sp-lib,$(lib))))
+
+endif