diff --git a/camera/ndk/impl/ACameraDevice.cpp b/camera/ndk/impl/ACameraDevice.cpp
new file mode 100644
index 0000000..0c6f8af
--- /dev/null
+++ b/camera/ndk/impl/ACameraDevice.cpp
@@ -0,0 +1,300 @@
+/*
+ * 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "ACameraDevice"
+
+#include <inttypes.h>
+#include "ACameraDevice.h"
+#include "ACameraMetadata.h"
+#include "ACaptureRequest.h"
+
+using namespace android;
+
+namespace android {
+// Static member definitions
+const char* CameraDevice::kContextKey   = "Context";
+const char* CameraDevice::kDeviceKey    = "Device";
+const char* CameraDevice::kErrorCodeKey = "ErrorCode";
+const char* CameraDevice::kCallbackKey  = "Callback";
+
+/**
+ * CameraDevice Implementation
+ */
+CameraDevice::CameraDevice(
+        const char* id,
+        ACameraDevice_StateCallbacks* cb,
+        std::unique_ptr<ACameraMetadata> chars,
+        ACameraDevice* wrapper) :
+        mCameraId(id),
+        mAppCallbacks(*cb),
+        mChars(std::move(chars)),
+        mServiceCallback(new ServiceCallback(this)),
+        mWrapper(wrapper),
+        mInError(false),
+        mError(ACAMERA_OK),
+        mIdle(true) {
+    mClosing = false;
+    // Setup looper thread to perfrom device callbacks to app
+    mCbLooper = new ALooper;
+    mCbLooper->setName("C2N-dev-looper");
+    status_t ret = mCbLooper->start(
+            /*runOnCallingThread*/false,
+            /*canCallJava*/       true,
+            PRIORITY_FOREGROUND);
+    mHandler = new CallbackHandler();
+    mCbLooper->registerHandler(mHandler);
+}
+
+CameraDevice::~CameraDevice() {
+    Mutex::Autolock _l(mDeviceLock);
+    if (mCbLooper != nullptr) {
+        mCbLooper->unregisterHandler(mHandler->id());
+        mCbLooper->stop();
+    }
+    mCbLooper.clear();
+    mHandler.clear();
+    if (!isClosed()) {
+        disconnectLocked();
+    }
+}
+
+// TODO: cached created request?
+camera_status_t
+CameraDevice::createCaptureRequest(
+        ACameraDevice_request_template templateId,
+        ACaptureRequest** request) const {
+    Mutex::Autolock _l(mDeviceLock);
+    camera_status_t ret = checkCameraClosedOrErrorLocked();
+    if (ret != ACAMERA_OK) {
+        return ret;
+    }
+    if (mRemote == nullptr) {
+        return ACAMERA_ERROR_CAMERA_DISCONNECTED;
+    }
+    CameraMetadata rawRequest;
+    status_t remoteRet = mRemote->createDefaultRequest(templateId, &rawRequest);
+    if (remoteRet == BAD_VALUE) {
+        ALOGW("Create capture request failed! template %d is not supported on this device",
+            templateId);
+        return ACAMERA_ERROR_UNSUPPORTED;
+    } else if (remoteRet != OK) {
+        ALOGE("Create capture request failed! error %d", remoteRet);
+        return ACAMERA_ERROR_UNKNOWN;
+    }
+    ACaptureRequest* outReq = new ACaptureRequest();
+    outReq->settings = new ACameraMetadata(rawRequest.release(), ACameraMetadata::ACM_REQUEST);
+    outReq->targets  = new ACameraOutputTargets();
+    *request = outReq;
+    return ACAMERA_OK;
+}
+
+void
+CameraDevice::disconnectLocked() {
+    if (mClosing.exchange(true)) {
+        // Already closing, just return
+        ALOGW("Camera device %s is already closing.", getId());
+        return;
+    }
+
+    if (mRemote != nullptr) {
+        mRemote->disconnect();
+    }
+    mRemote = nullptr;
+}
+
+void
+CameraDevice::setRemoteDevice(sp<ICameraDeviceUser> remote) {
+    Mutex::Autolock _l(mDeviceLock);
+    mRemote = remote;
+}
+
+camera_status_t
+CameraDevice::checkCameraClosedOrErrorLocked() const {
+    if (mRemote == nullptr) {
+        ALOGE("%s: camera device already closed", __FUNCTION__);
+        return ACAMERA_ERROR_CAMERA_DISCONNECTED;
+    }
+    if (mInError) {// triggered by onDeviceError
+        ALOGE("%s: camera device has encountered a serious error", __FUNCTION__);
+        return mError;
+    }
+    return ACAMERA_OK;
+}
+
+void
+CameraDevice::onCaptureErrorLocked(
+        ICameraDeviceCallbacks::CameraErrorCode errorCode,
+        const CaptureResultExtras& resultExtras) {
+    // TODO: implement!
+}
+
+void CameraDevice::CallbackHandler::onMessageReceived(
+        const sp<AMessage> &msg) {
+    switch (msg->what()) {
+        case kWhatOnDisconnected:
+        case kWhatOnError:
+            break;
+        default:
+            ALOGE("%s:Error: unknown device callback %d", __FUNCTION__, msg->what());
+            return;
+    }
+    // Check the common part of all message
+    void* context;
+    bool found = msg->findPointer(kContextKey, &context);
+    if (!found) {
+        ALOGE("%s: Cannot find callback context!", __FUNCTION__);
+        return;
+    }
+    ACameraDevice* dev;
+    found = msg->findPointer(kDeviceKey, (void**) &dev);
+    if (!found) {
+        ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
+        return;
+    }
+    switch (msg->what()) {
+        case kWhatOnDisconnected:
+        {
+            ACameraDevice_StateCallback onDisconnected;
+            found = msg->findPointer(kCallbackKey, (void**) &onDisconnected);
+            if (!found) {
+                ALOGE("%s: Cannot find onDisconnected!", __FUNCTION__);
+                return;
+            }
+            (*onDisconnected)(context, dev);
+            break;
+        }
+        case kWhatOnError:
+        {
+            ACameraDevice_ErrorStateCallback onError;
+            found = msg->findPointer(kCallbackKey, (void**) &onError);
+            if (!found) {
+                ALOGE("%s: Cannot find onError!", __FUNCTION__);
+                return;
+            }
+            int errorCode;
+            found = msg->findInt32(kErrorCodeKey, &errorCode);
+            if (!found) {
+                ALOGE("%s: Cannot find error code!", __FUNCTION__);
+                return;
+            }
+            (*onError)(context, dev, errorCode);
+        }
+    }
+}
+
+/**
+  * Camera service callback implementation
+  */
+void
+CameraDevice::ServiceCallback::onDeviceError(
+        CameraErrorCode errorCode,
+        const CaptureResultExtras& resultExtras) {
+    ALOGD("Device error received, code %d, frame number %" PRId64 ", request ID %d, subseq ID %d",
+            errorCode, resultExtras.frameNumber, resultExtras.requestId, resultExtras.burstId);
+
+    sp<CameraDevice> dev = mDevice.promote();
+    if (dev == nullptr) {
+        return; // device has been closed
+    }
+
+    Mutex::Autolock _l(dev->mDeviceLock);
+    if (dev->mRemote == nullptr) {
+        return; // device has been disconnected
+    }
+    switch (errorCode) {
+        case ERROR_CAMERA_DISCONNECTED:
+        {
+            // should be clear mRemote here?
+            // TODO: close current session
+            sp<AMessage> msg = new AMessage(kWhatOnDisconnected, dev->mHandler);
+            msg->setPointer(kContextKey, dev->mAppCallbacks.context);
+            msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
+            msg->setPointer(kCallbackKey, (void*) dev->mAppCallbacks.onDisconnected);
+            msg->post();
+            break;
+        }
+        default:
+            ALOGE("Unknown error from camera device: %d", errorCode);
+            // no break
+        case ERROR_CAMERA_DEVICE:
+        case ERROR_CAMERA_SERVICE:
+        {
+            dev->mInError = true;
+            switch (errorCode) {
+                case ERROR_CAMERA_DEVICE:
+                    dev->mError = ACAMERA_ERROR_CAMERA_DEVICE;
+                    break;
+                case ERROR_CAMERA_SERVICE:
+                    dev->mError = ACAMERA_ERROR_CAMERA_SERVICE;
+                    break;
+                default:
+                    dev->mError = ACAMERA_ERROR_UNKNOWN;
+                    break;
+            }
+            sp<AMessage> msg = new AMessage(kWhatOnError, dev->mHandler);
+            msg->setPointer(kContextKey, dev->mAppCallbacks.context);
+            msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
+            msg->setPointer(kCallbackKey, (void*) dev->mAppCallbacks.onError);
+            msg->setInt32(kErrorCodeKey, errorCode);
+            msg->post();
+            break;
+        }
+        case ERROR_CAMERA_REQUEST:
+        case ERROR_CAMERA_RESULT:
+        case ERROR_CAMERA_BUFFER:
+            dev->onCaptureErrorLocked(errorCode, resultExtras);
+            break;
+    }
+}
+
+void
+CameraDevice::ServiceCallback::onDeviceIdle() {
+    ALOGV("Camera is now idle");
+    sp<CameraDevice> dev = mDevice.promote();
+    if (dev == nullptr) {
+        return; // device has been closed
+    }
+
+    Mutex::Autolock _l(dev->mDeviceLock);
+    if (dev->mRemote == nullptr) {
+        return; // device has been disconnected
+    }
+    if (!dev->mIdle) {
+        // TODO: send idle callback to current session
+    }
+    dev->mIdle = true;
+}
+
+void
+CameraDevice::ServiceCallback::onCaptureStarted(
+        const CaptureResultExtras& resultExtras,
+        int64_t timestamp) {
+}
+
+void
+CameraDevice::ServiceCallback::onResultReceived(
+        const CameraMetadata& metadata,
+        const CaptureResultExtras& resultExtras) {
+}
+
+void
+CameraDevice::ServiceCallback::onPrepared(int) {
+    // Prepare not yet implemented in NDK
+    return;
+}
+
+} // namespace android
diff --git a/camera/ndk/impl/ACameraDevice.h b/camera/ndk/impl/ACameraDevice.h
new file mode 100644
index 0000000..061175c
--- /dev/null
+++ b/camera/ndk/impl/ACameraDevice.h
@@ -0,0 +1,158 @@
+/*
+ * 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.
+ */
+#ifndef _ACAMERA_DEVICE_H
+#define _ACAMERA_DEVICE_H
+
+#include <memory>
+#include <atomic>
+#include <utils/StrongPointer.h>
+#include <utils/Mutex.h>
+#include <utils/String8.h>
+
+#include <media/stagefright/foundation/ALooper.h>
+#include <media/stagefright/foundation/AHandler.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <camera/camera2/ICameraDeviceCallbacks.h>
+#include <camera/camera2/ICameraDeviceUser.h>
+
+#include <NdkCameraDevice.h>
+#include "ACameraMetadata.h"
+
+
+using namespace android;
+
+namespace android {
+
+struct CameraDevice final : public RefBase {
+  public:
+    CameraDevice(const char* id, ACameraDevice_StateCallbacks* cb,
+                  std::unique_ptr<ACameraMetadata> chars,
+                  ACameraDevice* wrapper);
+    ~CameraDevice();
+
+    inline const char* getId() const { return mCameraId.string(); }
+
+    camera_status_t createCaptureRequest(
+            ACameraDevice_request_template templateId,
+            ACaptureRequest** request) const;
+
+    // Callbacks from camera service
+    class ServiceCallback : public BnCameraDeviceCallbacks {
+      public:
+        ServiceCallback(CameraDevice* device) : mDevice(device) {}
+        void onDeviceError(CameraErrorCode errorCode,
+                           const CaptureResultExtras& resultExtras) override;
+        void onDeviceIdle() override;
+        void onCaptureStarted(const CaptureResultExtras& resultExtras,
+                              int64_t timestamp) override;
+        void onResultReceived(const CameraMetadata& metadata,
+                              const CaptureResultExtras& resultExtras) override;
+        void onPrepared(int streamId) override;
+      private:
+        const wp<CameraDevice> mDevice;
+    };
+    inline sp<ICameraDeviceCallbacks> getServiceCallback() { return mServiceCallback; };
+
+    // Camera device is only functional after remote being set
+    void setRemoteDevice(sp<ICameraDeviceUser> remote);
+
+  private:
+    void disconnectLocked(); // disconnect from camera service
+    camera_status_t checkCameraClosedOrErrorLocked() const;
+
+
+    mutable Mutex mDeviceLock;
+    const String8 mCameraId;                          // Camera ID
+    const ACameraDevice_StateCallbacks mAppCallbacks; // Callback to app
+    const std::unique_ptr<ACameraMetadata> mChars;    // Camera characteristics
+    const sp<ServiceCallback> mServiceCallback;
+    ACameraDevice* mWrapper;
+
+    // TODO: maybe a bool will suffice for synchronous implementation?
+    std::atomic_bool mClosing;
+    inline bool isClosed() { return mClosing; }
+
+    bool mInError;
+    camera_status_t mError;
+    void onCaptureErrorLocked(
+            ICameraDeviceCallbacks::CameraErrorCode errorCode,
+            const CaptureResultExtras& resultExtras);
+
+    bool mIdle;
+
+    sp<ICameraDeviceUser> mRemote;
+
+    // Looper thread to handle callback to app
+    sp<ALooper> mCbLooper;
+    // definition of handler and message
+    enum {
+        kWhatOnDisconnected,
+        kWhatOnError
+    };
+    static const char* kContextKey;
+    static const char* kDeviceKey;
+    static const char* kErrorCodeKey;
+    static const char* kCallbackKey;
+    class CallbackHandler : public AHandler {
+      public:
+        CallbackHandler() {}
+        void onMessageReceived(const sp<AMessage> &msg) override;
+    };
+    sp<CallbackHandler> mHandler;
+
+    inline ACameraDevice* getWrapper() { return mWrapper; };
+
+    // TODO: might need another looper/handler to handle callbacks from service
+
+
+};
+
+} // namespace android;
+
+/**
+ * ACameraDevice opaque struct definition
+ * Leave outside of android namespace because it's NDK struct
+ */
+struct ACameraDevice {
+    ACameraDevice(const char* id, ACameraDevice_StateCallbacks* cb,
+                  std::unique_ptr<ACameraMetadata> chars) :
+            mDevice(new CameraDevice(id, cb, std::move(chars), this)) {}
+
+    ~ACameraDevice() {};
+
+    inline const char* getId() const { return mDevice->getId(); }
+
+    camera_status_t createCaptureRequest(
+            ACameraDevice_request_template templateId,
+            ACaptureRequest** request) const {
+        return mDevice->createCaptureRequest(templateId, request);
+    }
+
+    inline sp<ICameraDeviceCallbacks> getServiceCallback() {
+        return mDevice->getServiceCallback();
+    };
+
+    // Camera device is only functional after remote being set
+    inline void setRemoteDevice(sp<ICameraDeviceUser> remote) {
+        mDevice->setRemoteDevice(remote);
+    }
+
+  private:
+    // TODO: might need an API to give wp of mDevice to capture session
+    sp<CameraDevice> mDevice;
+};
+
+#endif // _ACAMERA_DEVICE_H
diff --git a/camera/ndk/impl/ACameraManager.cpp b/camera/ndk/impl/ACameraManager.cpp
new file mode 100644
index 0000000..4014fd2
--- /dev/null
+++ b/camera/ndk/impl/ACameraManager.cpp
@@ -0,0 +1,478 @@
+/*
+ * 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "ACameraManager"
+
+#include <memory>
+#include "ACameraManager.h"
+#include "ACameraMetadata.h"
+#include "ACameraDevice.h"
+#include <utils/Vector.h>
+#include <stdlib.h>
+#include <camera/VendorTagDescriptor.h>
+
+using namespace android;
+
+//constants shared between ACameraManager and CameraManagerGlobal
+namespace {
+    const int kMaxCameraIdLen = 32;
+}
+
+namespace android {
+// Static member definitions
+const char* CameraManagerGlobal::kCameraIdKey   = "CameraId";
+const char* CameraManagerGlobal::kCallbackFpKey = "CallbackFp";
+const char* CameraManagerGlobal::kContextKey    = "CallbackContext";
+Mutex                CameraManagerGlobal::sLock;
+CameraManagerGlobal* CameraManagerGlobal::sInstance = nullptr;
+
+CameraManagerGlobal&
+CameraManagerGlobal::getInstance() {
+    Mutex::Autolock _l(sLock);
+    CameraManagerGlobal* instance = sInstance;
+    if (instance == nullptr) {
+        instance = new CameraManagerGlobal();
+        sInstance = instance;
+    }
+    return *instance;
+}
+
+CameraManagerGlobal::~CameraManagerGlobal() {
+    // clear sInstance so next getInstance call knows to create a new one
+    Mutex::Autolock _sl(sLock);
+    sInstance = nullptr;
+    Mutex::Autolock _l(mLock);
+    if (mCameraService != nullptr) {
+        IInterface::asBinder(mCameraService)->unlinkToDeath(mDeathNotifier);
+    }
+    mDeathNotifier.clear();
+    if (mCbLooper != nullptr) {
+        mCbLooper->unregisterHandler(mHandler->id());
+        mCbLooper->stop();
+    }
+    mCbLooper.clear();
+    mHandler.clear();
+    mCameraServiceListener.clear();
+    mCameraService.clear();
+}
+
+sp<ICameraService> CameraManagerGlobal::getCameraService() {
+    Mutex::Autolock _l(mLock);
+    if (mCameraService.get() == nullptr) {
+        sp<IServiceManager> sm = defaultServiceManager();
+        sp<IBinder> binder;
+        do {
+            binder = sm->getService(String16(kCameraServiceName));
+            if (binder != nullptr) {
+                break;
+            }
+            ALOGW("CameraService not published, waiting...");
+            usleep(kCameraServicePollDelay);
+        } while(true);
+        if (mDeathNotifier == nullptr) {
+            mDeathNotifier = new DeathNotifier(this);
+        }
+        binder->linkToDeath(mDeathNotifier);
+        mCameraService = interface_cast<ICameraService>(binder);
+
+        // Setup looper thread to perfrom availiability callbacks
+        if (mCbLooper == nullptr) {
+            mCbLooper = new ALooper;
+            mCbLooper->setName("C2N-mgr-looper");
+            status_t ret = mCbLooper->start(
+                    /*runOnCallingThread*/false,
+                    /*canCallJava*/       true,
+                    PRIORITY_FOREGROUND);
+            if (mHandler == nullptr) {
+                mHandler = new CallbackHandler();
+            }
+            mCbLooper->registerHandler(mHandler);
+        }
+
+        // register ICameraServiceListener
+        if (mCameraServiceListener == nullptr) {
+            mCameraServiceListener = new CameraServiceListener(this);
+        }
+        mCameraService->addListener(mCameraServiceListener);
+
+        // setup vendor tags
+        sp<VendorTagDescriptor> desc;
+        status_t ret = mCameraService->getCameraVendorTagDescriptor(/*out*/desc);
+
+        if (ret == OK) {
+            ret = VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
+            if (ret != OK) {
+                ALOGE("%s: Failed to set vendor tag descriptors, received error %s (%d)",
+                        __FUNCTION__, strerror(-ret), ret);
+            }
+        } else if (ret == -EOPNOTSUPP) {
+            ALOGW("%s: Camera HAL too old; does not support vendor tags",
+                    __FUNCTION__);
+            VendorTagDescriptor::clearGlobalVendorTagDescriptor();
+        } else {
+            ALOGE("%s: Failed to get vendor tag descriptors, received error %s (%d)",
+                    __FUNCTION__, strerror(-ret), ret);
+        }
+    }
+    ALOGE_IF(mCameraService == nullptr, "no CameraService!?");
+    return mCameraService;
+}
+
+void CameraManagerGlobal::DeathNotifier::binderDied(const wp<IBinder>&)
+{
+    ALOGE("Camera service binderDied!");
+    sp<CameraManagerGlobal> cm = mCameraManager.promote();
+    if (cm != nullptr) {
+        AutoMutex lock(cm->mLock);
+        for (auto pair : cm->mDeviceStatusMap) {
+            int32_t cameraId = pair.first;
+            cm->onStatusChangedLocked(
+                    ICameraServiceListener::STATUS_NOT_PRESENT, cameraId);
+        }
+        cm->mCameraService.clear();
+        // TODO: consider adding re-connect call here?
+    }
+}
+
+void CameraManagerGlobal::registerAvailabilityCallback(
+        const ACameraManager_AvailabilityCallbacks *callback) {
+    Mutex::Autolock _l(mLock);
+    Callback cb(callback);
+    auto pair = mCallbacks.insert(cb);
+    // Send initial callbacks if callback is newly registered
+    if (pair.second) {
+        for (auto pair : mDeviceStatusMap) {
+            int32_t cameraId = pair.first;
+            Status status = pair.second;
+
+            sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
+            ACameraManager_AvailabilityCallback cb = isStatusAvailable(status) ?
+                    callback->onCameraAvailable : callback->onCameraUnavailable;
+            msg->setPointer(kCallbackFpKey, (void *) cb);
+            msg->setPointer(kContextKey, callback->context);
+            msg->setInt32(kCameraIdKey, cameraId);
+            msg->post();
+        }
+    }
+}
+
+void CameraManagerGlobal::unregisterAvailabilityCallback(
+        const ACameraManager_AvailabilityCallbacks *callback) {
+    Mutex::Autolock _l(mLock);
+    Callback cb(callback);
+    mCallbacks.erase(cb);
+}
+
+bool CameraManagerGlobal::validStatus(Status status) {
+    switch (status) {
+        case ICameraServiceListener::STATUS_NOT_PRESENT:
+        case ICameraServiceListener::STATUS_PRESENT:
+        case ICameraServiceListener::STATUS_ENUMERATING:
+        case ICameraServiceListener::STATUS_NOT_AVAILABLE:
+            return true;
+        default:
+            return false;
+    }
+}
+
+bool CameraManagerGlobal::isStatusAvailable(Status status) {
+    switch (status) {
+        case ICameraServiceListener::STATUS_PRESENT:
+            return true;
+        default:
+            return false;
+    }
+}
+
+void CameraManagerGlobal::CallbackHandler::sendSingleCallback(
+        int32_t cameraId, void* context,
+        ACameraManager_AvailabilityCallback cb) const {
+    char cameraIdStr[kMaxCameraIdLen];
+    snprintf(cameraIdStr, sizeof(cameraIdStr), "%d", cameraId);
+    (*cb)(context, cameraIdStr);
+}
+
+void CameraManagerGlobal::CallbackHandler::onMessageReceived(
+        const sp<AMessage> &msg) {
+    switch (msg->what()) {
+        case kWhatSendSingleCallback:
+        {
+            ACameraManager_AvailabilityCallback cb;
+            void* context;
+            int32_t cameraId;
+            bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
+            if (!found) {
+                ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
+                return;
+            }
+            found = msg->findPointer(kContextKey, &context);
+            if (!found) {
+                ALOGE("%s: Cannot find callback context!", __FUNCTION__);
+                return;
+            }
+            found = msg->findInt32(kCameraIdKey, &cameraId);
+            if (!found) {
+                ALOGE("%s: Cannot find camera ID!", __FUNCTION__);
+                return;
+            }
+            sendSingleCallback(cameraId, context, cb);
+            break;
+        }
+        default:
+            ALOGE("%s: unknown message type %d", __FUNCTION__, msg->what());
+            break;
+    }
+}
+
+void CameraManagerGlobal::CameraServiceListener::onStatusChanged(
+        Status status, int32_t cameraId) {
+    sp<CameraManagerGlobal> cm = mCameraManager.promote();
+    if (cm == nullptr) {
+        ALOGE("Cannot deliver status change. Camera service died");
+        return;
+    }
+    cm->onStatusChanged(status, cameraId);
+}
+
+void CameraManagerGlobal::onStatusChanged(
+        Status status, int32_t cameraId) {
+    Mutex::Autolock _l(mLock);
+    onStatusChangedLocked(status, cameraId);
+}
+
+void CameraManagerGlobal::onStatusChangedLocked(
+        Status status, int32_t cameraId) {
+        if (!validStatus(status)) {
+            ALOGE("%s: Invalid status %d", __FUNCTION__, status);
+            return;
+        }
+
+        bool firstStatus = (mDeviceStatusMap.count(cameraId) == 0);
+        Status oldStatus = firstStatus ?
+                status : // first status
+                mDeviceStatusMap[cameraId];
+
+        if (!firstStatus &&
+                isStatusAvailable(status) == isStatusAvailable(oldStatus)) {
+            // No status update. No need to send callback
+            return;
+        }
+
+        // Iterate through all registered callbacks
+        mDeviceStatusMap[cameraId] = status;
+        for (auto cb : mCallbacks) {
+            sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
+            ACameraManager_AvailabilityCallback cbFp = isStatusAvailable(status) ?
+                    cb.mAvailable : cb.mUnavailable;
+            msg->setPointer(kCallbackFpKey, (void *) cbFp);
+            msg->setPointer(kContextKey, cb.mContext);
+            msg->setInt32(kCameraIdKey, cameraId);
+            msg->post();
+        }
+}
+
+} // namespace android
+
+/**
+ * ACameraManger Implementation
+ */
+camera_status_t
+ACameraManager::getOrCreateCameraIdListLocked(ACameraIdList** cameraIdList) {
+    if (mCachedCameraIdList.numCameras == kCameraIdListNotInit) {
+        int numCameras = 0;
+        Vector<char *> cameraIds;
+        sp<ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService();
+        if (cs == nullptr) {
+            ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
+            return ACAMERA_ERROR_CAMERA_DISCONNECTED;
+        }
+        // Get number of cameras
+        int numAllCameras = cs->getNumberOfCameras(ICameraService::CAMERA_TYPE_ALL);
+        // Filter API2 compatible cameras and push to cameraIds
+        for (int i = 0; i < numAllCameras; i++) {
+            // TODO: Only suppot HALs that supports API2 directly now
+            status_t camera2Support = cs->supportsCameraApi(i, ICameraService::API_VERSION_2);
+            char buf[kMaxCameraIdLen];
+            if (camera2Support == OK) {
+                numCameras++;
+                mCameraIds.insert(i);
+                snprintf(buf, sizeof(buf), "%d", i);
+                size_t cameraIdSize = strlen(buf) + 1;
+                char *cameraId = new char[cameraIdSize];
+                if (!cameraId) {
+                    ALOGE("Allocate memory for ACameraIdList failed!");
+                    return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
+                }
+                strlcpy(cameraId, buf, cameraIdSize);
+                cameraIds.push(cameraId);
+            }
+        }
+        mCachedCameraIdList.numCameras = numCameras;
+        mCachedCameraIdList.cameraIds = new const char*[numCameras];
+        if (!mCachedCameraIdList.cameraIds) {
+            ALOGE("Allocate memory for ACameraIdList failed!");
+            return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
+        }
+        for (int i = 0; i < numCameras; i++) {
+            mCachedCameraIdList.cameraIds[i] = cameraIds[i];
+        }
+    }
+    *cameraIdList = &mCachedCameraIdList;
+    return ACAMERA_OK;
+}
+
+camera_status_t
+ACameraManager::getCameraIdList(ACameraIdList** cameraIdList) {
+    Mutex::Autolock _l(mLock);
+    ACameraIdList* cachedList;
+    camera_status_t ret = getOrCreateCameraIdListLocked(&cachedList);
+    if (ret != ACAMERA_OK) {
+        ALOGE("Get camera ID list failed! err: %d", ret);
+        return ret;
+    }
+
+    int numCameras = cachedList->numCameras;
+    ACameraIdList *out = new ACameraIdList;
+    if (!out) {
+        ALOGE("Allocate memory for ACameraIdList failed!");
+        return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
+    }
+    out->numCameras = numCameras;
+    out->cameraIds = new const char*[numCameras];
+    if (!out->cameraIds) {
+        ALOGE("Allocate memory for ACameraIdList failed!");
+        return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
+    }
+    for (int i = 0; i < numCameras; i++) {
+        const char* src = cachedList->cameraIds[i];
+        size_t dstSize = strlen(src) + 1;
+        char* dst = new char[dstSize];
+        if (!dst) {
+            ALOGE("Allocate memory for ACameraIdList failed!");
+            return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
+        }
+        strlcpy(dst, src, dstSize);
+        out->cameraIds[i] = dst;
+    }
+    *cameraIdList = out;
+    return ACAMERA_OK;
+}
+
+void
+ACameraManager::deleteCameraIdList(ACameraIdList* cameraIdList) {
+    if (cameraIdList != nullptr) {
+        if (cameraIdList->cameraIds != nullptr) {
+            for (int i = 0; i < cameraIdList->numCameras; i ++) {
+                delete[] cameraIdList->cameraIds[i];
+            }
+            delete[] cameraIdList->cameraIds;
+        }
+        delete cameraIdList;
+    }
+}
+
+camera_status_t ACameraManager::getCameraCharacteristics(
+        const char *cameraIdStr, ACameraMetadata **characteristics) {
+    Mutex::Autolock _l(mLock);
+    ACameraIdList* cachedList;
+    // Make sure mCameraIds is initialized
+    camera_status_t ret = getOrCreateCameraIdListLocked(&cachedList);
+    if (ret != ACAMERA_OK) {
+        ALOGE("%s: Get camera ID list failed! err: %d", __FUNCTION__, ret);
+        return ret;
+    }
+    int cameraId = atoi(cameraIdStr);
+    if (mCameraIds.count(cameraId) == 0) {
+        ALOGE("%s: Camera ID %s does not exist!", __FUNCTION__, cameraIdStr);
+        return ACAMERA_ERROR_INVALID_PARAMETER;
+    }
+    sp<ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService();
+    if (cs == nullptr) {
+        ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
+        return ACAMERA_ERROR_CAMERA_DISCONNECTED;
+    }
+    CameraMetadata rawMetadata;
+    status_t serviceRet = cs->getCameraCharacteristics(cameraId, &rawMetadata);
+    if (serviceRet != OK) {
+        ALOGE("Get camera characteristics from camera service failed! Err %d", ret);
+        return ACAMERA_ERROR_UNKNOWN; // should not reach here
+    }
+
+    *characteristics = new ACameraMetadata(
+            rawMetadata.release(), ACameraMetadata::ACM_CHARACTERISTICS);
+    return ACAMERA_OK;
+}
+
+camera_status_t
+ACameraManager::openCamera(
+        const char* cameraId,
+        ACameraDevice_StateCallbacks* callback,
+        /*out*/ACameraDevice** outDevice) {
+    ACameraMetadata* rawChars;
+    camera_status_t ret = getCameraCharacteristics(cameraId, &rawChars);
+    Mutex::Autolock _l(mLock);
+    if (ret != ACAMERA_OK) {
+        ALOGE("%s: cannot get camera characteristics for camera %s. err %d",
+                __FUNCTION__, cameraId, ret);
+        return ACAMERA_ERROR_INVALID_PARAMETER;
+    }
+    std::unique_ptr<ACameraMetadata> chars(rawChars);
+    rawChars = nullptr;
+
+    ACameraDevice* device = new ACameraDevice(cameraId, callback, std::move(chars));
+
+    sp<ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService();
+    if (cs == nullptr) {
+        ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
+        return ACAMERA_ERROR_CAMERA_DISCONNECTED;
+    }
+
+    int id = atoi(cameraId);
+    sp<ICameraDeviceCallbacks> callbacks = device->getServiceCallback();
+    sp<ICameraDeviceUser> deviceRemote;
+    // No way to get package name from native.
+    // Send a zero length package name and let camera service figure it out from UID
+    status_t serviceRet = cs->connectDevice(
+            callbacks, id, String16(""),
+            ICameraService::USE_CALLING_UID, /*out*/deviceRemote);
+
+    if (serviceRet != OK) {
+        ALOGE("%s: connect camera device failed! err %d", __FUNCTION__, serviceRet);
+        // TODO: generate better error message here
+        delete device;
+        return ACAMERA_ERROR_CAMERA_DISCONNECTED;
+    }
+    if (deviceRemote == nullptr) {
+        ALOGE("%s: connect camera device failed! remote device is null", __FUNCTION__);
+        delete device;
+        return ACAMERA_ERROR_CAMERA_DISCONNECTED;
+    }
+    device->setRemoteDevice(deviceRemote);
+    *outDevice = device;
+    return ACAMERA_OK;
+}
+
+ACameraManager::~ACameraManager() {
+    Mutex::Autolock _l(mLock);
+    if (mCachedCameraIdList.numCameras != kCameraIdListNotInit) {
+        for (int i = 0; i < mCachedCameraIdList.numCameras; i++) {
+            delete[] mCachedCameraIdList.cameraIds[i];
+        }
+        delete[] mCachedCameraIdList.cameraIds;
+    }
+}
+
diff --git a/camera/ndk/impl/ACameraManager.h b/camera/ndk/impl/ACameraManager.h
new file mode 100644
index 0000000..b68685d
--- /dev/null
+++ b/camera/ndk/impl/ACameraManager.h
@@ -0,0 +1,184 @@
+/*
+ * 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.
+ */
+
+#ifndef _ACAMERA_MANAGER_H
+#define _ACAMERA_MANAGER_H
+
+#include "NdkCameraManager.h"
+
+#include <camera/CameraMetadata.h>
+#include <camera/ICameraService.h>
+#include <camera/ICameraServiceListener.h>
+#include <binder/IServiceManager.h>
+#include <utils/StrongPointer.h>
+#include <utils/Mutex.h>
+
+#include <media/stagefright/foundation/ALooper.h>
+#include <media/stagefright/foundation/AHandler.h>
+#include <media/stagefright/foundation/AMessage.h>
+
+#include <set>
+#include <map>
+
+using namespace android;
+
+namespace android {
+
+/**
+ * Per-process singleton instance of CameraManger. Shared by all ACameraManager
+ * instances. Created when first ACameraManager is created and destroyed when
+ * all ACameraManager instances are deleted.
+ *
+ * TODO: maybe CameraManagerGlobal is better sutied in libcameraclient?
+ */
+class CameraManagerGlobal final : public RefBase {
+  public:
+    static CameraManagerGlobal& getInstance();
+    sp<ICameraService> getCameraService();
+
+    void registerAvailabilityCallback(
+            const ACameraManager_AvailabilityCallbacks *callback);
+    void unregisterAvailabilityCallback(
+            const ACameraManager_AvailabilityCallbacks *callback);
+
+  private:
+    sp<ICameraService> mCameraService;
+    const int          kCameraServicePollDelay = 500000; // 0.5s
+    const char*        kCameraServiceName      = "media.camera";
+    Mutex              mLock;
+
+    class DeathNotifier : public IBinder::DeathRecipient {
+      public:
+        DeathNotifier(CameraManagerGlobal* cm) : mCameraManager(cm) {}
+      protected:
+        // IBinder::DeathRecipient implementation
+        virtual void binderDied(const wp<IBinder>& who);
+      private:
+        const wp<CameraManagerGlobal> mCameraManager;
+    };
+    sp<DeathNotifier> mDeathNotifier;
+
+    class CameraServiceListener final : public BnCameraServiceListener {
+      public:
+        CameraServiceListener(CameraManagerGlobal* cm) : mCameraManager(cm) {}
+        virtual void onStatusChanged(Status status, int32_t cameraId);
+
+        // Torch API not implemented yet
+        virtual void onTorchStatusChanged(TorchStatus, const String16&) {};
+      private:
+        const wp<CameraManagerGlobal> mCameraManager;
+    };
+    sp<CameraServiceListener> mCameraServiceListener;
+
+    // Wrapper of ACameraManager_AvailabilityCallbacks so we can store it in std::set
+    struct Callback {
+        Callback(const ACameraManager_AvailabilityCallbacks *callback) :
+            mAvailable(callback->onCameraAvailable),
+            mUnavailable(callback->onCameraUnavailable),
+            mContext(callback->context) {}
+
+        bool operator == (const Callback& other) const {
+            return (mAvailable == other.mAvailable &&
+                    mUnavailable == other.mUnavailable &&
+                    mContext == other.mContext);
+        }
+        bool operator != (const Callback& other) const {
+            return !(*this == other);
+        }
+        bool operator < (const Callback& other) const {
+            if (*this == other) return false;
+            if (mContext != other.mContext) return mContext < other.mContext;
+            if (mAvailable != other.mAvailable) return mAvailable < other.mAvailable;
+            return mUnavailable < other.mUnavailable;
+        }
+        bool operator > (const Callback& other) const {
+            return (*this != other && !(*this < other));
+        }
+        ACameraManager_AvailabilityCallback mAvailable;
+        ACameraManager_AvailabilityCallback mUnavailable;
+        void*                               mContext;
+    };
+    std::set<Callback> mCallbacks;
+
+    // definition of handler and message
+    enum {
+        kWhatSendSingleCallback
+    };
+    static const char* kCameraIdKey;
+    static const char* kCallbackFpKey;
+    static const char* kContextKey;
+    class CallbackHandler : public AHandler {
+      public:
+        CallbackHandler() {}
+        void onMessageReceived(const sp<AMessage> &msg) override;
+      private:
+        inline void sendSingleCallback(
+                int32_t cameraId, void* context,
+                ACameraManager_AvailabilityCallback cb) const;
+    };
+    sp<CallbackHandler> mHandler;
+    sp<ALooper>         mCbLooper; // Looper thread where callbacks actually happen on
+
+    typedef ICameraServiceListener::Status Status;
+    void onStatusChanged(Status status, int32_t cameraId);
+    void onStatusChangedLocked(Status status, int32_t cameraId);
+    // Utils for status
+    static bool validStatus(Status status);
+    static bool isStatusAvailable(Status status);
+
+    // Map camera_id -> status
+    std::map<int32_t, Status> mDeviceStatusMap;
+
+    // For the singleton instance
+    static Mutex sLock;
+    static CameraManagerGlobal* sInstance;
+    CameraManagerGlobal() {};
+    ~CameraManagerGlobal();
+};
+
+} // namespace android;
+
+/**
+ * ACameraManager opaque struct definition
+ * Leave outside of android namespace because it's NDK struct
+ */
+struct ACameraManager {
+    ACameraManager() :
+            mCachedCameraIdList({kCameraIdListNotInit, nullptr}),
+            mGlobalManager(&(CameraManagerGlobal::getInstance())) {}
+    ~ACameraManager();
+    camera_status_t getCameraIdList(ACameraIdList** cameraIdList);
+    static void     deleteCameraIdList(ACameraIdList* cameraIdList);
+
+    camera_status_t getCameraCharacteristics(
+            const char *cameraId, ACameraMetadata **characteristics);
+    camera_status_t openCamera(const char* cameraId,
+                               ACameraDevice_StateCallbacks* callback,
+                               /*out*/ACameraDevice** device);
+
+  private:
+    camera_status_t getOrCreateCameraIdListLocked(ACameraIdList** cameraIdList);
+
+    enum {
+        kCameraIdListNotInit = -1
+    };
+    Mutex         mLock;
+    std::set<int> mCameraIds;          // Init by getOrCreateCameraIdListLocked
+    ACameraIdList mCachedCameraIdList; // Init by getOrCreateCameraIdListLocked
+    sp<CameraManagerGlobal> mGlobalManager;
+};
+
+#endif //_ACAMERA_MANAGER_H
diff --git a/camera/ndk/impl/ACameraMetadata.cpp b/camera/ndk/impl/ACameraMetadata.cpp
new file mode 100644
index 0000000..25571c5
--- /dev/null
+++ b/camera/ndk/impl/ACameraMetadata.cpp
@@ -0,0 +1,219 @@
+/*
+ * 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "ACameraMetadata"
+
+#include "ACameraMetadata.h"
+#include <utils/Vector.h>
+
+using namespace android;
+
+/**
+ * ACameraMetadata Implementation
+ */
+ACameraMetadata::ACameraMetadata(camera_metadata_t* buffer, ACAMERA_METADATA_TYPE type) :
+        mData(buffer), mType(type) {
+    filterUnsupportedFeatures();
+}
+
+bool
+ACameraMetadata::isNdkSupportedCapability(int32_t capability) {
+    switch (capability) {
+        case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE:
+        case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR:
+        case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING:
+        case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW:
+        case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS:
+        case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE:
+        case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT:
+            return true;
+        case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING:
+        case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING:
+        case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO:
+            return false;
+        default:
+            // Newly defined capabilities will be unsupported by default (blacklist)
+            // TODO: Should we do whitelist or blacklist here?
+            ALOGE("%s: Unknonwn capability %d", __FUNCTION__, capability);
+            return false;
+    }
+}
+
+void
+ACameraMetadata::filterUnsupportedFeatures() {
+    // Hide unsupported capabilities (reprocessing)
+    camera_metadata_entry entry = mData.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
+    if (entry.count == 0 || entry.type != ACAMERA_TYPE_BYTE) {
+        ALOGE("%s: malformed available capability key! count %zu, type %d",
+                __FUNCTION__, entry.count, entry.type);
+        return;
+    }
+
+    Vector<uint8_t> capabilities;
+    capabilities.setCapacity(entry.count);
+    for (size_t i = 0; i < entry.count; i++) {
+        uint8_t capability = entry.data.u8[i];
+        if (isNdkSupportedCapability(capability)) {
+            capabilities.push(capability);
+        }
+    }
+    mData.update(ANDROID_REQUEST_AVAILABLE_CAPABILITIES, capabilities);
+    // TODO: Hide unsupported streams (input/bidirectional streams)
+}
+
+bool
+ACameraMetadata::isVendorTag(const uint32_t tag) {
+    uint32_t tag_section = tag >> 16;
+    if (tag_section >= VENDOR_SECTION) {
+        return true;
+    }
+    return false;
+}
+
+camera_status_t
+ACameraMetadata::getConstEntry(uint32_t tag, ACameraMetadata_const_entry* entry) const {
+    if (entry == nullptr) {
+        return ACAMERA_ERROR_INVALID_PARAMETER;
+    }
+
+    camera_metadata_ro_entry rawEntry = mData.find(tag);
+    if (rawEntry.count == 0) {
+        ALOGE("%s: cannot find metadata tag %d", __FUNCTION__, tag);
+        return ACAMERA_ERROR_METADATA_NOT_FOUND;
+    }
+    entry->tag = tag;
+    entry->type = rawEntry.type;
+    entry->count = rawEntry.count;
+    entry->data.u8 = rawEntry.data.u8;
+    return ACAMERA_OK;
+}
+
+camera_status_t
+ACameraMetadata::update(uint32_t tag, uint32_t count, const uint8_t* data) {
+    return updateImpl<uint8_t>(tag, count, data);
+}
+
+camera_status_t
+ACameraMetadata::update(uint32_t tag, uint32_t count, const int32_t* data) {
+    return updateImpl<int32_t>(tag, count, data);
+}
+
+camera_status_t
+ACameraMetadata::update(uint32_t tag, uint32_t count, const float* data) {
+    return updateImpl<float>(tag, count, data);
+}
+
+camera_status_t
+ACameraMetadata::update(uint32_t tag, uint32_t count, const double* data) {
+    return updateImpl<double>(tag, count, data);
+}
+
+camera_status_t
+ACameraMetadata::update(uint32_t tag, uint32_t count, const int64_t* data) {
+    return updateImpl<int64_t>(tag, count, data);
+}
+
+camera_status_t
+ACameraMetadata::update(uint32_t tag, uint32_t count, const ACameraMetadata_rational* data) {
+    return updateImpl<camera_metadata_rational_t>(tag, count, data);
+}
+
+
+// TODO: some of key below should be hidden from user
+// ex: ACAMERA_REQUEST_ID and ACAMERA_REPROCESS_EFFECTIVE_EXPOSURE_FACTOR
+/*@O~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
+ * The key entries below this point are generated from metadata
+ * definitions in /system/media/camera/docs. Do not modify by hand or
+ * modify the comment blocks at the start or end.
+ *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~*/
+
+bool
+ACameraMetadata::isCaptureRequestTag(const uint32_t tag) {
+    // Skip check for vendor keys
+    if (isVendorTag(tag)) {
+        return true;
+    }
+
+    switch (tag) {
+        case ACAMERA_COLOR_CORRECTION_MODE:
+        case ACAMERA_COLOR_CORRECTION_TRANSFORM:
+        case ACAMERA_COLOR_CORRECTION_GAINS:
+        case ACAMERA_COLOR_CORRECTION_ABERRATION_MODE:
+        case ACAMERA_CONTROL_AE_ANTIBANDING_MODE:
+        case ACAMERA_CONTROL_AE_EXPOSURE_COMPENSATION:
+        case ACAMERA_CONTROL_AE_LOCK:
+        case ACAMERA_CONTROL_AE_MODE:
+        case ACAMERA_CONTROL_AE_REGIONS:
+        case ACAMERA_CONTROL_AE_TARGET_FPS_RANGE:
+        case ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER:
+        case ACAMERA_CONTROL_AF_MODE:
+        case ACAMERA_CONTROL_AF_REGIONS:
+        case ACAMERA_CONTROL_AF_TRIGGER:
+        case ACAMERA_CONTROL_AWB_LOCK:
+        case ACAMERA_CONTROL_AWB_MODE:
+        case ACAMERA_CONTROL_AWB_REGIONS:
+        case ACAMERA_CONTROL_CAPTURE_INTENT:
+        case ACAMERA_CONTROL_EFFECT_MODE:
+        case ACAMERA_CONTROL_MODE:
+        case ACAMERA_CONTROL_SCENE_MODE:
+        case ACAMERA_CONTROL_VIDEO_STABILIZATION_MODE:
+        case ACAMERA_CONTROL_POST_RAW_SENSITIVITY_BOOST:
+        case ACAMERA_EDGE_MODE:
+        case ACAMERA_FLASH_MODE:
+        case ACAMERA_HOT_PIXEL_MODE:
+        case ACAMERA_JPEG_GPS_COORDINATES:
+        case ACAMERA_JPEG_GPS_PROCESSING_METHOD:
+        case ACAMERA_JPEG_GPS_TIMESTAMP:
+        case ACAMERA_JPEG_ORIENTATION:
+        case ACAMERA_JPEG_QUALITY:
+        case ACAMERA_JPEG_THUMBNAIL_QUALITY:
+        case ACAMERA_JPEG_THUMBNAIL_SIZE:
+        case ACAMERA_LENS_APERTURE:
+        case ACAMERA_LENS_FILTER_DENSITY:
+        case ACAMERA_LENS_FOCAL_LENGTH:
+        case ACAMERA_LENS_FOCUS_DISTANCE:
+        case ACAMERA_LENS_OPTICAL_STABILIZATION_MODE:
+        case ACAMERA_NOISE_REDUCTION_MODE:
+        case ACAMERA_REQUEST_ID:
+        case ACAMERA_SCALER_CROP_REGION:
+        case ACAMERA_SENSOR_EXPOSURE_TIME:
+        case ACAMERA_SENSOR_FRAME_DURATION:
+        case ACAMERA_SENSOR_SENSITIVITY:
+        case ACAMERA_SENSOR_TEST_PATTERN_DATA:
+        case ACAMERA_SENSOR_TEST_PATTERN_MODE:
+        case ACAMERA_SHADING_MODE:
+        case ACAMERA_STATISTICS_FACE_DETECT_MODE:
+        case ACAMERA_STATISTICS_HOT_PIXEL_MAP_MODE:
+        case ACAMERA_STATISTICS_LENS_SHADING_MAP_MODE:
+        case ACAMERA_TONEMAP_CURVE_BLUE:
+        case ACAMERA_TONEMAP_CURVE_GREEN:
+        case ACAMERA_TONEMAP_CURVE_RED:
+        case ACAMERA_TONEMAP_MODE:
+        case ACAMERA_TONEMAP_GAMMA:
+        case ACAMERA_TONEMAP_PRESET_CURVE:
+        case ACAMERA_LED_TRANSMIT:
+        case ACAMERA_BLACK_LEVEL_LOCK:
+        case ACAMERA_REPROCESS_EFFECTIVE_EXPOSURE_FACTOR:
+            return true;
+        default:
+            return false;
+    }
+}
+
+/*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
+ * End generated code
+ *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/
diff --git a/camera/ndk/impl/ACameraMetadata.h b/camera/ndk/impl/ACameraMetadata.h
new file mode 100644
index 0000000..36a9a9a
--- /dev/null
+++ b/camera/ndk/impl/ACameraMetadata.h
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+#ifndef _ACAMERA_METADATA_H
+#define _ACAMERA_METADATA_H
+
+#include <sys/types.h>
+#include <camera/CameraMetadata.h>
+
+#include "NdkCameraMetadata.h"
+
+using namespace android;
+
+/**
+ * ACameraMetadata opaque struct definition
+ * Leave outside of android namespace because it's NDK struct
+ */
+struct ACameraMetadata {
+  public:
+    typedef enum {
+        ACM_CHARACTERISTICS, // Read only
+        ACM_REQUEST,         // Read/Write
+        ACM_RESULT,          // Read only
+    } ACAMERA_METADATA_TYPE;
+
+    // Takes ownership of pass-in buffer
+    ACameraMetadata(camera_metadata_t *buffer, ACAMERA_METADATA_TYPE type);
+    // Clone
+    ACameraMetadata(const ACameraMetadata& other) :
+            mData(other.mData), mType(other.mType) {};
+
+    camera_status_t getConstEntry(uint32_t tag, ACameraMetadata_const_entry* entry) const;
+
+    camera_status_t update(uint32_t tag, uint32_t count, const uint8_t* data);
+    camera_status_t update(uint32_t tag, uint32_t count, const int32_t* data);
+    camera_status_t update(uint32_t tag, uint32_t count, const float* data);
+    camera_status_t update(uint32_t tag, uint32_t count, const double* data);
+    camera_status_t update(uint32_t tag, uint32_t count, const int64_t* data);
+    camera_status_t update(uint32_t tag, uint32_t count, const ACameraMetadata_rational* data);
+
+  private:
+    bool isNdkSupportedCapability(const int32_t capability);
+    inline bool isVendorTag(const uint32_t tag);
+    bool isCaptureRequestTag(const uint32_t tag);
+    void filterUnsupportedFeatures(); // Hide features not yet supported by NDK
+
+    template<typename INTERNAL_T, typename NDK_T>
+    camera_status_t updateImpl(uint32_t tag, uint32_t count, const NDK_T* data) {
+        if (mType != ACM_REQUEST) {
+            ALOGE("Error: Write to metadata is only allowed for capture request!");
+            return ACAMERA_ERROR_INVALID_PARAMETER;
+        }
+        if (!isCaptureRequestTag(tag)) {
+            ALOGE("Error: tag %d is not writable!", tag);
+            return ACAMERA_ERROR_INVALID_PARAMETER;
+        }
+
+        // Here we have to use reinterpret_cast because the NDK data type is
+        // exact copy of internal data type but they do not inherit from each other
+        status_t ret = mData.update(tag, reinterpret_cast<const INTERNAL_T*>(data), count);
+        if (ret == OK) {
+            return ACAMERA_OK;
+        } else {
+            return ACAMERA_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    CameraMetadata mData;
+    const ACAMERA_METADATA_TYPE mType;
+};
+
+#endif // _ACAMERA_METADATA_H
diff --git a/camera/ndk/impl/ACaptureRequest.h b/camera/ndk/impl/ACaptureRequest.h
new file mode 100644
index 0000000..6bd8406
--- /dev/null
+++ b/camera/ndk/impl/ACaptureRequest.h
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+#ifndef _ACAPTURE_REQUEST_H
+#define _ACAPTURE_REQUEST_H
+
+#include "NdkCaptureRequest.h"
+#include <set>
+
+using namespace android;
+
+struct ACameraOutputTarget {
+    ACameraOutputTarget(ANativeWindow* window) : mWindow(window) {};
+
+    bool operator == (const ACameraOutputTarget& other) const {
+        return mWindow == other.mWindow;
+    }
+    bool operator != (const ACameraOutputTarget& other) const {
+        return mWindow != other.mWindow;
+    }
+    bool operator < (const ACameraOutputTarget& other) const {
+        return mWindow < other.mWindow;
+    }
+    bool operator > (const ACameraOutputTarget& other) const {
+        return mWindow > other.mWindow;
+    }
+
+    ANativeWindow* mWindow;
+};
+
+struct ACameraOutputTargets {
+    std::set<ACameraOutputTarget> mOutputs;
+};
+
+struct ACaptureRequest {
+    ACameraMetadata*      settings;
+    ACameraOutputTargets* targets;
+};
+
+#endif // _ACAPTURE_REQUEST_H
